我试图重写一种使用存在类型的方法,但我无法破译错误:
use std::result;
pub struct Child {
pub value: u32,
}
pub struct Parent {
pub name: u32,
}
impl Parent {
pub fn process(&self, _l: &Child) -> result::Result<(), ()> {
Ok(())
}
pub fn convert(&self, l: &Child) {
()
}
pub fn looper(&self, l: Vec<Child>) -> impl Iterator<Item = Result<Child, ()>> {
let x: Vec<_> = l.into_iter()
.map(|tr| self.process(&tr).map(|_| tr))
.collect(); // Calling collect() here forces all debits to complete
let y = x.into_iter().map(|d| {
d.map(|c| {
self.convert(&c);
c
})
});
y
}
}
fn main() {
let b = Parent { name: 0 };
let l = vec![Child { value: 10 }, Child { value: 20 }];
let _: Vec<Child> = b.looper(l).map(|x| x.unwrap()).collect();
}
我的错误消息指出:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:25:35
|
25 | let y = x.into_iter().map(|d| {
| ___________________________________^
26 | | d.map(|c| {
27 | | self.convert(&c);
28 | | c
29 | | })
30 | | });
| |_________^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 20:5...
--> src/main.rs:20:5
|
20 | / pub fn looper(&self, l: Vec<Child>) -> impl Iterator<Item = Result<Child, ()>> {
21 | | let x: Vec<_> = l.into_iter()
22 | | .map(|tr| self.process(&tr).map(|_| tr))
23 | | .collect(); // Calling collect() here forces all debits to complete
... |
31 | | y
32 | | }
| |_____^
= note: ...so that the types are compatible:
expected &&Parent
found &&Parent
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that return value is valid for the call
--> src/main.rs:20:44
|
20 | pub fn looper(&self, l: Vec<Child>) -> impl Iterator<Item = Result<Child, ()>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
答案 0 :(得分:2)
let y = x.into_iter().map(|d| {
d.map(|c| {
self.convert(&c); // <--- This
c
})
});
这会在返回的迭代器中借用&self
,因为每次调用convert
时,都需要将&self
的实例传递给函数(即使它未使用)。
要明确使生命周期正确,您需要的语法是:
fn foo<'a>(/* ... */) -> impl 'a + Trait
e.g。
pub fn looper<'a>(&'a self, l: /* ... */) -> impl 'a + Iterator<Item = Result<Child, ()>> { /* ... */ }
即。返回与借用对象具有相同生命周期的impl Iterator<Item = Result<Child, ()>>
。
默认情况是impl Foo
返回'static
生命周期实例,在这种情况下无效,因为convert
借用了&self
。
像这样:
use std::result;
pub struct Child {
pub value: u32,
}
pub struct Parent {
pub name: u32,
}
impl Parent {
pub fn process(&self, _l: &Child) -> result::Result<(), ()> {
Ok(())
}
pub fn convert(&self, l: &Child) {
()
}
pub fn looper<'a>(&'a self, l: Vec<Child>) -> impl 'a + Iterator<Item = Result<Child, ()>> {
let x: Vec<_> = l.into_iter()
.map(|tr| self.process(&tr).map(|_| tr))
.collect(); // Calling collect() here forces all debits to complete
let y = x.into_iter().map(move |d| {
d.map(|c| {
self.convert(&c);
c
})
});
y
}
}
fn main() {
let b = Parent { name: 0 };
let l = vec![Child { value: 10 }, Child { value: 20 }];
let k = b.looper(l);
drop(b); // <-- Doesn't work.
let _: Vec<Child> = k.map(|x| x.unwrap()).collect();
}
请注意,编译器正确地抱怨在迭代器未解析时试图丢弃b
:
error[E0505]: cannot move out of `b` because it is borrowed
--> src/main.rs:39:10
|
38 | let k = b.looper(l);
| - borrow of `b` occurs here
39 | drop(b);
| ^ move out of `b` occurs here
或者,您可以从&self
convert
的引用
pub fn convert(l: &Child) {
()
}