Serde::Deserialize 的实现不够通用
implementation of Serde::Deserialize is not general enough
我正在使用 event_emmiter_rs for event handling in my app. This library allows you to subscribe to events with callbacks and also fire those events. Events are in the form of (strings, value) and callbacks are in the form of closures that take in a value parameter. Values sent through the event callbacks must implement Serde::Deserialize. We can see this here in the docs。所以我创建了这个简单的设置:
use event_emitter_rs::EventEmitter;
use serde::Serialize;
use serde::Deserialize;
use std::borrow::Cow;
#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(bound(deserialize = "'de: 'static"))]
//#[serde(bound(deserialize = "'de: 'a"))] using the 'a lifetime gives same error
pub struct DraggableInfo<'a>{
parent: WidgetValue<'a>,
index: WidgetValue<'a>,
draggable_id: WidgetValue<'a>,
}
impl<'a> DraggableInfo<'a>{
pub fn new(parent: &'static str, index: u32, draggable_id: &'static str)->Self{
DraggableInfo{
parent: WidgetValue::CString(Cow::Borrowed(parent)),
index: WidgetValue::Unsized32(index),
draggable_id: WidgetValue::CString(Cow::Borrowed(draggable_id)),
}
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub enum WidgetValue<'a>{
Integer32(i32),
Unsized32(u32),
CString(Cow<'a, str>)
}
fn main(){
let mut event_emitter = EventEmitter::new();
event_emitter.on("Print Draggable Value", |dragValue: DraggableInfo| {dbg!(dragValue);});
event_emitter.emit("Print Draggable Value", DraggableInfo::new("root", 0, "layer 1"));
}
但这会导致错误消息:
error: implementation of `Deserialize` is not general enough
--> src\main.rs:34:19
|
34 | event_emitter.on("Print Draggable Value", |dragValue: DraggableInfo| {dbg!(dragValue);});
| ^^ implementation of `Deserialize` is not general enough
|
= note: `DraggableInfo<'_>` must implement `Deserialize<'0>`, for any lifetime `'0`...
= note: ...but `DraggableInfo<'_>` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
我不确定消息所指的 Deserialize<'0>
和 Deserialize<'1>
生命周期是什么,或者当编译器说 impl “过于笼统”时它的确切含义。我该如何解决这个错误?
问题在评论中被驳回,但您的具体问题在此行中很突出:
#[serde(bound(deserialize = "'de: 'static"))]
如Serde guide预先警告:
Note that <T> where T: Deserialize<'static>
is never what you want. Also Deserialize<'de> + 'static
is never what you want. Generally writing 'static
anywhere near Deserialize
is a sign of being on the wrong track. Use one of the above bounds instead.
这应该具有实际意义:您永远不想从 100% 的静态数据反序列化。你拥有的那些 WidgetValue
,它们会在运行时动态地进出范围(created/destroyed),对吧?..
但是,当您将带有 reference 的 CString
变体定义到原始输入缓冲区(发生反序列化的事件有效负载)时 - 您必须确保不单个 WidgetValue
永远超过其输入缓冲区。这就是 Rust 生命周期的目的,它们编码机器检查的保证 Bad Things™ 不会发生。
再次来自评论:简单的解决方案是拥有数据而不是借用(引用)它,即
pub enum WidgetValue {
Integer32(i32),
Unsized32(u32),
CString(String),
}
... 但这种简单性会让您付出性能成本,无论何时传递 WidgetValue
s 时,都会在堆分配和无偿字符串复制方面付出代价。您将失去 Serde 支持的 zero-copy capacity。并不是说它本质上是不好的;也许这个价格适合您的应用。
但是,许多程序员选择 Rust 用于那些性能很重要的应用程序。在安全方面也毫不妥协。也就是说:让我们亲自动手吧。
注意:Unsized32
是矛盾的,你可能想写 Unsigned32
.
注意:在DraggableInfo::new
签名中,为什么要求借用的字符串切片有'static
生命周期?这太严格了。只需 'a
就足够了。
the error is clear that the type needs to implement Deserialize for any lifetime
确实; .on
signature 没有 'de
作为通用参数:
pub fn on<F, T>(&mut self, event: &str, callback: F) -> String where
T: Deserialize<'de>,
F: Fn(T) + 'static + Sync + Send,
这意味着调用者无法选择生命周期。这有可能是无意的,也许可以尝试询问作者或 event_emitter_rs
图书馆;可能是一个微妙的错误,可能是设计使然。
顺便说一句:如果你想使用 serde_json::from_reader
for deserializing truly dynamically in a stream — this whole zero-copy endeavor will not work out. That's expressed in that DeserializeOwned
constraint. This fact is also mentioned in the guide、For example when deserializing from an IO stream no data can be borrowed.
在这一点上,我放弃了进一步的研究,因为我是在从流中解析 JSON 的上下文中访问这个问题的。这意味着我别无选择,只能执行 DeserializeOwned
(即在我的数据结构中使用拥有的 String
而不是 &'a str
)。这也是有道理的,因为流数据是短暂的,所以从中借用根本行不通。
我正在使用 event_emmiter_rs for event handling in my app. This library allows you to subscribe to events with callbacks and also fire those events. Events are in the form of (strings, value) and callbacks are in the form of closures that take in a value parameter. Values sent through the event callbacks must implement Serde::Deserialize. We can see this here in the docs。所以我创建了这个简单的设置:
use event_emitter_rs::EventEmitter;
use serde::Serialize;
use serde::Deserialize;
use std::borrow::Cow;
#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(bound(deserialize = "'de: 'static"))]
//#[serde(bound(deserialize = "'de: 'a"))] using the 'a lifetime gives same error
pub struct DraggableInfo<'a>{
parent: WidgetValue<'a>,
index: WidgetValue<'a>,
draggable_id: WidgetValue<'a>,
}
impl<'a> DraggableInfo<'a>{
pub fn new(parent: &'static str, index: u32, draggable_id: &'static str)->Self{
DraggableInfo{
parent: WidgetValue::CString(Cow::Borrowed(parent)),
index: WidgetValue::Unsized32(index),
draggable_id: WidgetValue::CString(Cow::Borrowed(draggable_id)),
}
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub enum WidgetValue<'a>{
Integer32(i32),
Unsized32(u32),
CString(Cow<'a, str>)
}
fn main(){
let mut event_emitter = EventEmitter::new();
event_emitter.on("Print Draggable Value", |dragValue: DraggableInfo| {dbg!(dragValue);});
event_emitter.emit("Print Draggable Value", DraggableInfo::new("root", 0, "layer 1"));
}
但这会导致错误消息:
error: implementation of `Deserialize` is not general enough
--> src\main.rs:34:19
|
34 | event_emitter.on("Print Draggable Value", |dragValue: DraggableInfo| {dbg!(dragValue);});
| ^^ implementation of `Deserialize` is not general enough
|
= note: `DraggableInfo<'_>` must implement `Deserialize<'0>`, for any lifetime `'0`...
= note: ...but `DraggableInfo<'_>` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
我不确定消息所指的 Deserialize<'0>
和 Deserialize<'1>
生命周期是什么,或者当编译器说 impl “过于笼统”时它的确切含义。我该如何解决这个错误?
问题在评论中被驳回,但您的具体问题在此行中很突出:
#[serde(bound(deserialize = "'de: 'static"))]
如Serde guide预先警告:
Note that
<T> where T: Deserialize<'static>
is never what you want. AlsoDeserialize<'de> + 'static
is never what you want. Generally writing'static
anywhere nearDeserialize
is a sign of being on the wrong track. Use one of the above bounds instead.
这应该具有实际意义:您永远不想从 100% 的静态数据反序列化。你拥有的那些 WidgetValue
,它们会在运行时动态地进出范围(created/destroyed),对吧?..
但是,当您将带有 reference 的 CString
变体定义到原始输入缓冲区(发生反序列化的事件有效负载)时 - 您必须确保不单个 WidgetValue
永远超过其输入缓冲区。这就是 Rust 生命周期的目的,它们编码机器检查的保证 Bad Things™ 不会发生。
再次来自评论:简单的解决方案是拥有数据而不是借用(引用)它,即
pub enum WidgetValue {
Integer32(i32),
Unsized32(u32),
CString(String),
}
... 但这种简单性会让您付出性能成本,无论何时传递 WidgetValue
s 时,都会在堆分配和无偿字符串复制方面付出代价。您将失去 Serde 支持的 zero-copy capacity。并不是说它本质上是不好的;也许这个价格适合您的应用。
但是,许多程序员选择 Rust 用于那些性能很重要的应用程序。在安全方面也毫不妥协。也就是说:让我们亲自动手吧。
注意:Unsized32
是矛盾的,你可能想写 Unsigned32
.
注意:在DraggableInfo::new
签名中,为什么要求借用的字符串切片有'static
生命周期?这太严格了。只需 'a
就足够了。
the error is clear that the type needs to implement Deserialize for any lifetime
确实; .on
signature 没有 'de
作为通用参数:
pub fn on<F, T>(&mut self, event: &str, callback: F) -> String where
T: Deserialize<'de>,
F: Fn(T) + 'static + Sync + Send,
这意味着调用者无法选择生命周期。这有可能是无意的,也许可以尝试询问作者或 event_emitter_rs
图书馆;可能是一个微妙的错误,可能是设计使然。
顺便说一句:如果你想使用 serde_json::from_reader
for deserializing truly dynamically in a stream — this whole zero-copy endeavor will not work out. That's expressed in that DeserializeOwned
constraint. This fact is also mentioned in the guide、For example when deserializing from an IO stream no data can be borrowed.
在这一点上,我放弃了进一步的研究,因为我是在从流中解析 JSON 的上下文中访问这个问题的。这意味着我别无选择,只能执行 DeserializeOwned
(即在我的数据结构中使用拥有的 String
而不是 &'a str
)。这也是有道理的,因为流数据是短暂的,所以从中借用根本行不通。