[英]How do you create a generic function in Rust with a trait requiring a lifetime?
我正在尝试编写一个与数据库一起工作的特征,并表示可以存储的内容。 为此,特征继承自其他特征,其中包括serde::Deserialize
特征。
trait Storable<'de>: Serialize + Deserialize<'de> {
fn global_id() -> &'static [u8];
fn instance_id(&self) -> Vec<u8>;
}
struct Example {
a: u8,
b: u8
}
impl<'de> Storable<'de> for Example {
fn global_id() -> &'static [u8] { b"p" }
fn instance_id(&self) -> Vec<u8> { vec![self.a, self.b] }
}
接下来,我尝试使用通用函数编写此数据:
pub fn put<'de, S: Storable>(&mut self, obj: &'de S) -> Result<(), String> {
...
let value = bincode::serialize(obj, bincode::Infinite);
...
db.put(key, value).map_err(|e| e.to_string())
}
但是,我收到以下错误:
error[E0106]: missing lifetime specifier
--> src/database.rs:180:24
|
180 | pub fn put<'de, S: Storable>(&mut self, obj: &'de S) -> Result<(), String> {
| ^^^^^^^^ expected lifetime parameter
我该如何解决这个问题,可能完全避免它?
你有'de
生命在错误的地方 - 你需要它来指定Storable
的参数,而不是参考obj
的生命周期。
代替
fn to_json<'de, S: Storable>(obj: &'de S) -> String {
使用
fn to_json<'de, S: Storable<'de>>(obj: &S) -> String {
游乐场 。
obj
的生命周期在这里并不重要,因为你没有返回从它派生的任何值。 所有你需要证明的是, S
实现了Storable<'de>
一段生命'de
。
如果你想彻底消除'de
degether,你应该使用DeserializeOwned
,正如另一个答案所描述的那样。
您已使用通用参数定义了Storable
,在本例中为生命周期。 这意味着通用参数必须在整个应用程序中传播:
fn put<'de, S: Storable<'de>>(obj: &'de S) -> Result<(), String> { /* ... */ }
您还可以决定使用通用特定的。 这可以通过具体类型或生命周期(例如'static
)来完成,或者通过将其放在特征对象后面来完成。
Serde还有一个关于解串器生命周期的综合页面 。 它提到你也可以选择使用DeserializeOwned
。
trait Storable: Serialize + DeserializeOwned { /* ... */ }
您也可以使用与DeserializeOwned
相同的概念作为您自己的特征:
trait StorableOwned: for<'de> Storable<'de> { }
fn put<'de, S: StorableOwned>(obj: &'de S) -> Result<(), String> {
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.