我正在尝试实现一个查找函数,该函数将返回对self
值中包含的值的可变引用。通常,由于返回的引用指向lookup
函数(self.verts
)之外的数据,因此借用检查器看不出有任何问题。但是,在我的情况下,我在返回引用并将其绑定到新的拥有名称之前过滤self.verts
。当我尝试从本地拥有的数组返回一个值时,我得到编译时错误:
error: `vs` does not live long enough
--> src/util/graph.rs:18:37
|
18 | if vs.len() > 0 { Some(&mut vs[0]) } else { None }
| ^^ does not live long enough
19 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the body at 16:75...
--> src/util/graph.rs:16:76
|
16 | pub fn lookup_id<'a>(&'a mut self, id: &str) -> Option<&'a mut Vertex> {
| ____________________________________________________________________________^ starting here...
17 | | let vs:Vec<&mut Vertex> = self.verts.iter_mut().filter(|x| x.id == id).collect();
18 | | if vs.len() > 0 { Some(&mut vs[0]) } else { None }
19 | | }
| |_____^ ...ending here
我知道我无法返回对本地拥有的内容的引用,我怀疑编译器是如何解释我的代码的,但这不是我想要做的。想要做的是返回对self.verts
向量中的值的引用,以便返回的引用具有相同的生命周期和正在执行查找的结构。这是我目前的尝试:
pub fn lookup_id<'a>(&'a mut self, id: &str) -> Option<&'a mut Vertex> {
let vs:Vec<&'a mut Vertex> = self.verts.iter_mut().filter(|x| x.id == id).collect();
if vs.len() > 0 { Some(&mut vs[0]) } else { None }
}
此代码无法编译,因为vs does not live long enough
。如何告诉编译器想要返回vs
中包含的引用而不是vs
的引用?
答案 0 :(得分:2)
您正在返回&mut &mut Vertex
。
如果丢弃剩余的元素,可以进行延迟计算:
self.verts.iter_mut().filter(|x| x.id == id).next()
答案 1 :(得分:0)
我怀疑&mut &mut Vertex
之类的东西。不幸的是,如果&mut
之前没有vs
,则会出现其他几个编译器错误。事实证明,Rust在索引时返回引用,这是我不知道的。我必须检查std::vec
模块,我发现remove()
直接返回值。此代码有效:
pub fn lookup_id(&mut self, id: &str) -> Option<&mut Vertex> {
let mut vs:Vec<&mut Vertex> = self.verts.iter_mut().filter(|x| x.id == id).collect();
if vs.len() > 0 { Some(vs.remove(0)) } else { None }
}
然而,这个版本更清晰:
pub fn lookup_id(&self, id: &str) -> Option<&Vertex> {
self.verts.iter().find(|x| x.id == id)
}