如何在Rust中创建具有需要生命周期特征的泛型函数? [英] How do you create a generic function in Rust with a trait requiring a lifetime?

查看:133
本文介绍了如何在Rust中创建具有需要生命周期特征的泛型函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个可与​​数据库一起使用并表示可以存储的特征.为此,该特征从其他特征继承而来,包括serde::Deserialize特征.

I am trying to write a trait which works with a database and represents something which can be stored. To do this, the trait inherits from others, which includes the serde::Deserialize trait.

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] }
}

接下来,我正在尝试使用通用函数写入此数据:

Next, I am trying to write this data using a generic function:

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

在操场上的最小示例.

我该如何解决,可能完全避免呢?

How would I resolve this, possibly avoid it altogether?

推荐答案

您已使用通用参数(在这种情况下为生命周期)定义了Storable.这意味着必须在整个应用程序中传播通用参数:

You have defined Storable with a generic parameter, in this case a lifetime. That means that the generic parameter has to be propagated throughout the entire application:

fn put<'de, S: Storable<'de>>(obj: &'de S) -> Result<(), String> { /* ... */ }

您还可以决定使泛型特定.可以使用具体的类型或生存期(例如'static),也可以将其放在特征对象后.

You can also decide to make the generic specific. That can be done with a concrete type or lifetime (e.g. 'static), or by putting it behind a trait object.

Serde还具有有关解串器寿命的综合页面.它提到您也可以选择使用DeserializeOwned.

Serde also has a comprehensive page about deserializer lifetimes. It mentions that you can choose to use DeserializeOwned as well.

trait Storable: Serialize + DeserializeOwned { /* ... */ }

您也可以将与DeserializeOwned相同的概念用于自己的特征:

You can use the same concept as DeserializeOwned for your own trait as well:

trait StorableOwned: for<'de> Storable<'de> { }

fn put<'de, S: StorableOwned>(obj: &'de S) -> Result<(), String> {

这篇关于如何在Rust中创建具有需要生命周期特征的泛型函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆