如何在包含 &'static str 的结构上实现 serde::Deserialize?
How to implement serde::Deserialize on struct containing &'static str?
我正在尝试在 SourceConfig
结构上实现 serde::Deserialize
,它包装了一个包含 &'static str
的结构以及它自己的一些数据 (playground):
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Config {
pub name: &'static str,
}
#[derive(Serialize, Deserialize)]
struct SourceConfig {
config: Config,
id: u32,
}
但这给了我一生的错误:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'de` as defined on the impl at 8:21...
--> src/lib.rs:8:21
|
8 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
note: ...so that the types are compatible
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
= note: expected `SeqAccess<'_>`
found `SeqAccess<'de>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
= note: expected `Deserialize<'_>`
found `Deserialize<'static>`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'de` as defined on the impl at 8:21...
--> src/lib.rs:8:21
|
8 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
note: ...so that the types are compatible
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
= note: expected `MapAccess<'_>`
found `MapAccess<'de>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
= note: expected `Deserialize<'_>`
found `Deserialize<'static>`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
我尝试将 #[serde(borrow)]
添加到 SourceConfig
中的 config
,但这不起作用,因为 Config
不是借用的。将它添加到 Config
中的 name
也不起作用。如何在 SourceConfig
上正确实施 Deserialize
?
您可以在 SourceConfig
结构上添加一个 bound,这样 'de
生命周期等于 'static
生命周期。
#[derive(Debug, serde::Deserialize)]
pub struct Config {
pub name: &'static str,
}
#[derive(Debug, serde::Deserialize)]
#[serde(bound(deserialize = "'de: 'static"))]
struct SourceConfig {
config: Config,
id: u32,
}
fn main() {
let j = r#"
{
"id": 123,
"config": {
"name": "John Smith"
}
}
"#;
let sc: SourceConfig = serde_json::from_str(&j).unwrap();
dbg!(sc);
}
但是,您可能不想反序列化 &'static str
,因为这需要您有一个 &'static str
来借用。这将您限制为字符串文字,或者您需要泄漏内存才能获取 &'static str
。
你可能想要一个 String
或者,如果你想支持字符串文字,一个 Cow<'a, str>
.
&'a str
的另一个问题是,如果字符串是用转义序列序列化的,它将无法工作。例如,包含换行符的 JSON 字符串将具有 \n
,在反序列化过程中需要将其替换,因此如果您使用 &'a str
.
将失败
我正在尝试在 SourceConfig
结构上实现 serde::Deserialize
,它包装了一个包含 &'static str
的结构以及它自己的一些数据 (playground):
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Config {
pub name: &'static str,
}
#[derive(Serialize, Deserialize)]
struct SourceConfig {
config: Config,
id: u32,
}
但这给了我一生的错误:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'de` as defined on the impl at 8:21...
--> src/lib.rs:8:21
|
8 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
note: ...so that the types are compatible
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
= note: expected `SeqAccess<'_>`
found `SeqAccess<'de>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
= note: expected `Deserialize<'_>`
found `Deserialize<'static>`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'de` as defined on the impl at 8:21...
--> src/lib.rs:8:21
|
8 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
note: ...so that the types are compatible
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
= note: expected `MapAccess<'_>`
found `MapAccess<'de>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
= note: expected `Deserialize<'_>`
found `Deserialize<'static>`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
我尝试将 #[serde(borrow)]
添加到 SourceConfig
中的 config
,但这不起作用,因为 Config
不是借用的。将它添加到 Config
中的 name
也不起作用。如何在 SourceConfig
上正确实施 Deserialize
?
您可以在 SourceConfig
结构上添加一个 bound,这样 'de
生命周期等于 'static
生命周期。
#[derive(Debug, serde::Deserialize)]
pub struct Config {
pub name: &'static str,
}
#[derive(Debug, serde::Deserialize)]
#[serde(bound(deserialize = "'de: 'static"))]
struct SourceConfig {
config: Config,
id: u32,
}
fn main() {
let j = r#"
{
"id": 123,
"config": {
"name": "John Smith"
}
}
"#;
let sc: SourceConfig = serde_json::from_str(&j).unwrap();
dbg!(sc);
}
但是,您可能不想反序列化 &'static str
,因为这需要您有一个 &'static str
来借用。这将您限制为字符串文字,或者您需要泄漏内存才能获取 &'static str
。
你可能想要一个 String
或者,如果你想支持字符串文字,一个 Cow<'a, str>
.
&'a str
的另一个问题是,如果字符串是用转义序列序列化的,它将无法工作。例如,包含换行符的 JSON 字符串将具有 \n
,在反序列化过程中需要将其替换,因此如果您使用 &'a str
.