首页 文章

如何在返回对外部引用的过滤向量的引用时安抚借用检查器

提问于
浏览
2

我正在尝试实现一个查找函数,该函数将返回对 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 的引用?

2 回答

  • 0

    你回来了 &mut &mut Vertex .

    如果您丢弃剩余的元素,则可以进行延迟计算: self.verts.iter_mut().filter(|x| x.id == id).next()

  • 2

    我怀疑像 &mut &mut Vertex 这样的东西 . 不幸的是,如果没有 &mut 之前的 &mut ,还有其他几个编译器错误 . 事实证明,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)
    }
    

相关问题