사용자 정의 Serde (1.0) 직렬화 및 직렬화 해제 메소드가 관련된 프로젝트에서이 테스트 루틴을 사용하여 객체와 직렬을 직렬화하면 동일한 객체가 생성되는지 여부를 확인했습니다.Serde 직렬화와 직렬화를 검사하기위한 일반 함수를 작성하려면 어떻게해야합니까?
// let o: T = ...;
let buf: Vec<u8> = to_vec(&o).unwrap();
let o2: T = from_slice(&buf).unwrap();
assert_eq!(o, o2);
이 인라인을 사용하면 효과가 있습니다. 재사용을 향한 나의 다음 단계는이 목적을 위해 기능을 check_serde
으로 만드는 것이었다.
pub fn check_serde<T>(o: T)
where
T: Debug + PartialEq<T> + Serialize + DeserializeOwned,
{
let buf: Vec<u8> = to_vec(&o).unwrap();
let o2: T = from_slice(&buf).unwrap();
assert_eq!(o, o2);
}
이 평생의 경계를 가지는 유형에 대한 유형을 소유 잘 작동하지만,하지 (Playground) :
check_serde(5);
check_serde(vec![1, 2, 5]);
check_serde("five".to_string());
check_serde("wait"); // [E0279]
오류 : 나는 함수 작업을하고자으로
error[E0279]: the requirement `for<'de> 'de : ` is not satisfied (`expected bound lifetime parameter 'de, found concrete lifetime`)
--> src/main.rs:24:5
|
24 | check_serde("wait"); // [E0277]
| ^^^^^^^^^^^
|
= note: required because of the requirements on the impl of `for<'de> serde::Deserialize<'de>` for `&str`
= note: required because of the requirements on the impl of `serde::de::DeserializeOwned` for `&str`
= note: required by `check_serde`
이러한 경우 (문자열 슬라이스가있는 구조체 포함) 명시 적 객체 직렬화 수명이있는 새 버전을 시도했습니다.
pub fn check_serde<'a, T>(o: &'a T)
where
T: Debug + PartialEq<T> + Serialize + Deserialize<'a>,
{
let buf: Vec<u8> = to_vec(o).unwrap();
let o2: T = from_slice(&buf).unwrap();
assert_eq!(o, &o2);
}
check_serde(&5);
check_serde(&vec![1, 2, 5]);
check_serde(&"five".to_string());
check_serde(&"wait"); // [E0405]
이 구현으로 인해 다른 문제가 발생하며 컴파일되지 않습니다 (Playground).
error[E0597]: `buf` does not live long enough
--> src/main.rs:14:29
|
14 | let o2: T = from_slice(&buf).unwrap();
| ^^^ does not live long enough
15 | assert_eq!(o, &o2);
16 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 10:1...
--> src/main.rs:10:1
|
10 |/pub fn check_serde<'a, T>(o: &'a T)
11 | | where T: Debug + PartialEq<T> + Serialize + Deserialize<'a>
12 | | {
13 | | let buf: Vec<u8> = to_vec(o).unwrap();
14 | | let o2: T = from_slice(&buf).unwrap();
15 | | assert_eq!(o, &o2);
16 | | }
| |_^
는 나는 이미이 일 것으로 예상 한 :이 버전은 직렬화 된 내용이 (그래서 직렬화 복원 오브젝트가) 사실이 아니다 입력 개체로 오래 사는 것을 의미한다. 버퍼는 함수의 범위만큼 살아 있어야합니다.
제 3의 시도는 원래 입력의 소유 버전을 빌드하여 수명 기간 경계가 서로 다른 직렬화되지 않은 객체를 갖는 문제를 피하기위한 것입니다. ToOwned
특성은이 사용 사례에 적합한 것으로 보입니다. 우리는 첫 번째 버전과 같은 오류 종류에 우연히 발견,
check_serde(&5);
check_serde(&vec![1, 2, 5]);
check_serde(&"five".to_string());
check_serde("wait");
check_serde(&("There's more!", 36)); // [E0279]
을 다시 :
pub fn check_serde<'a, T: ?Sized>(o: &'a T)
where
T: Debug + ToOwned + PartialEq<<T as ToOwned>::Owned> + Serialize,
<T as ToOwned>::Owned: Debug + DeserializeOwned,
{
let buf: Vec<u8> = to_vec(&o).unwrap();
let o2: T::Owned = from_slice(&buf).unwrap();
assert_eq!(o, &o2);
}
이 지금은 일반 문자열 조각에 대한 기능을 작동 할 수있게하지만, 복합 개체에 대해 (Playground)을 포함하지 않는 :
error[E0279]: the requirement `for<'de> 'de : ` is not satisfied (`expected bound lifetime parameter 'de, found concrete lifetime`)
--> src/main.rs:25:5
|
25 | check_serde(&("There's more!", 36)); // [E0279]
| ^^^^^^^^^^^
|
= note: required because of the requirements on the impl of `for<'de> serde::Deserialize<'de>` for `&str`
= note: required because of the requirements on the impl of `for<'de> serde::Deserialize<'de>` for `(&str, {integer})`
= note: required because of the requirements on the impl of `serde::de::DeserializeOwned` for `(&str, {integer})`
= note: required by `check_serde`
허락합니다. 어떻게 Serde를 사용하여 객체를 직렬화하고 새로운 객체로 역 직렬화하는 제네릭 함수를 만들 수 있습니까? 특히이 기능을 녹 (안정 또는 야간)에서 만들 수 있습니까? 그렇다면 구현에 대한 조정 사항이 누락 되었습니까?