简体   繁体   中英

Rust: cannot infer an appropriate lifetime for autoref due to conflicting requirements

Minimal reproducible code:

trait VecExt<T, R> {
    fn map(&self, f: impl Fn(&T) -> R) -> Vec<R>;
}

impl<T, R> VecExt<T, R> for Vec<T> {
    fn map(&self, f: impl Fn(&T) -> R) -> Vec<R> {
        self.iter().map(f).collect()
    }
}

struct A {
    a: Vec<Option<String>>
}

impl A {
    fn foo(&self) -> Vec<Option<&String>> {
        self.a.map(|o| o.as_ref())
    }
}

Getting error message:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements

When using self.a.iter().map(|o| o.as_ref()).collect() , it compiles.

I've already read the explain document, but I still don't know why this error occurs and how to solve it.

When the map call in A.foo is replaced with the code from the map function, it compiles, which indicates that the issue is with the trait definition not constraining the lifetime of the argument passed to the closure.

In the case of fn map(&self, f: impl Fn(&T) -> R) -> Vec<R> , the lifetime of the reference passed as &T in impl Fn(&T) -> R must live for at least as long as the &self argument passed into it. The following changes should make it compile

trait VecExt<'a, T, R> where T: 'a {
    fn map(&'a self, f: impl Fn(&'a T) -> R) -> Vec<R>;
}

impl<'a, T, R> VecExt<'a, T, R> for Vec<T> where T: 'a {
    fn map(&'a self, f: impl Fn(&'a T) -> R) -> Vec<R> {
        self.iter().map(f).collect()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM