如何在 Rust 中创建一个具有需要生命周期的特征的通用函数?

2023-12-12

我正在尝试编写一个与数据库一起使用并代表可以存储的内容的特征。为此,该特征继承自其他特征,其中包括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] }
}

接下来,我尝试使用通用函数写入这些数据:

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

操场上的最小例子。

我该如何解决这个问题,或者完全避免它?


你已经定义了Storable具有通用参数,在本例中是生命周期。这意味着通用参数必须在整个应用程序中传播:

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

您还可以决定将通用性具体化。这可以通过具体类型或生命周期来完成(例如'static),或者将其放在特征对象后面。

赛德也有有关解串器生命周期的综合页面。它提到您可以选择使用DeserializeOwned以及。

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

您可以使用与以下相同的概念DeserializeOwned也适合你自己的特质:

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

fn put<'de, S: StorableOwned>(obj: &'de S) -> Result<(), String> {
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Rust 中创建一个具有需要生命周期的特征的通用函数? 的相关文章

随机推荐