Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

borrowed value does not live long enough when write an generic object mapping function in rust

I want to mapping object using this code snippnet in rust:

fn map_entity_vec<T: 'static,E>(sources:Vec<T>) -> Vec<E> where E: From<&'static T>, E: Clone {
    if sources.is_empty() {
        return Vec::new();
    }
    let mut responses= Vec::new();
    for source in sources {
        let template_response = E::from(&source);
        responses.push(template_response.clone());
    }
    return responses;
}

the compiler shows eror:

error[E0597]: `source` does not live long enough
  --> src/main.rs:13:41
   |
13 |         let template_response = E::from(&source);
   |                                 --------^^^^^^^-
   |                                 |       |
   |                                 |       borrowed value does not live long enough
   |                                 argument requires that `source` is borrowed for `'static`
14 |         responses.push(template_response.clone());
15 |     }
   |     - `source` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.

what should I do to avoid this problem? I have tried to remove the lifetime static but the compiler tell me it should be added. I am still not figure out what should I do to make the object mapping function work.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You need to use Higher Rank Trait Bounds here to satisfy the compiler, not make everything 'static:

fn map_entity_vec<T, E>(sources: Vec<T>) -> Vec<E>
where
    for<'a> E: From<&'a T>,
    E: Clone,
{
    if sources.is_empty() {
        return Vec::new();
    }
    let mut responses = Vec::new();
    for source in sources {
        let template_response = E::from(&source);
        responses.push(template_response.clone());
    }
    return responses;
}

This can also be simplified using the iterator functions to:

fn map_entity_vec_2<T, E>(sources: Vec<T>) -> Vec<E>
where
    for<'a> E: From<&'a T> + Clone,
{
    sources.iter().map(E::from).collect()
}

Playground

Edit: You also don’t need E: Clone since E::from returns E not &E:

fn map_entity_vec_3<T, E>(sources: Vec<T>) -> Vec<E>
where
    for<'a> E: From<&'a T>,
{
    sources.iter().map(E::from).collect()
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading