当迭代器使用容器时,是否可以从循环中返回容器?

时间:2017-03-13 13:20:46

标签: rust

我有一个BufReader的迭代器,想要返回BufReader。这个例子很简单,只适合使用return,但真正的代码结构更复杂,return不合适:

fn f() -> Result<Vec<i32>, &'static str> {
    let ret = vec![1, 2, 3];

    for i in ret.iter() {
        if *i == 2 {
            return Ok(ret);
        }
    }
    Err("no element")
}

这会编译错误:

error[E0505]: cannot move out of `ret` because it is borrowed
   |
11 |     for i in ret.iter() {
   |              --- borrow of `ret` occurs here
12 |         if *i == 2 {
13 |             return Ok(ret);
   |                       ^^^ move out of `ret` occurs here

如果所有引用都是本地的,为什么这是一个错误?引用是否仍然存在真的很重要吗?

2 个答案:

答案 0 :(得分:2)

目前借用程序员不支持这一点,但无论如何它都不会是惯用语。惯用的解决方案是

if ret.contains(&2) {
    return Ok(ret);
}

由于您的实际代码是BufReader,我假设您指的是bytes方法返回的迭代器。在这种情况下,惯用解决方案将是以下的变体。

if ret.bytes().any(|b| b == Ok(2)) {
    return Ok(ret);
}

答案 1 :(得分:2)

  

如果所有引用都是本地引用,为什么会出现错误?

嗯,不完全是。 iter()调用似乎没有借用任何东西,但确实如此。签名是fn iter(&self) -> Iter<T>。当您致电ret.iter()时,您实际上正在呼叫iter(&ret),这是不可避免地借用ret。借用将在for循环的范围之前有效,这是while循环本身的语法糖,直到迭代器的next函数不再返回值。