How do you create a generic function in Rust with a lifelong attribute?

I am trying to write a tag that works with a database and represents something that can be saved. For this, a trait is inherited from others, which includes a trait 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] }
}

Next, I try 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())
}

However, I get the following error:

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

Minimal example on the playground.

How can I solve this problem, is it possible to avoid it altogether?

+4
source share
2 answers

You determined Storablewith a common parameter, in this case, the lifetime. This means that the generic parameter should be distributed throughout the application:

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> {
+3

'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, DeserializeOwned, .

+4

Source: https://habr.com/ru/post/1687169/


All Articles