【问题标题】:mutable borrow starts here in previous iteration of loop可变借用在循环的上一次迭代中从这里开始
【发布时间】:2021-05-15 15:32:40
【问题描述】:

Rust 新手,我在 StackOverflow 中寻找过类似的案例(并且有很多),但它们的场景都略有不同,我无法找到解决此问题的方法。

我正在尝试遍历一些字符串,将它们传递给对它们应用一些操作的函数,并最终将结果推送到向量中。 (实际情况对于map 场景来说太复杂了)。

playground

mod lifetime_test {
    fn parse_line<'a>(item: &'a str, target: &'a mut Vec<&'a str>) {
        // ... use item to compute a result
        target.push("result");
    }

    fn parse_file() {
        let mut target: Vec<&str> = Vec::new();
        let source: Vec<&str> = Vec::new();

        // ... fill source with strings from file

        for item in source {
            parse_line(item, &mut target);
        }
    }
}

fn main() {}

以上内容无法编译:mutable borrow starts here in previous iteration of loop parse_line 调用。

我想我理解为什么它抱怨多个可变借用,但我找不到传递字符串和向量的方法,并让 parse_line 函数将其结果存储到传递的向量中。

在实际情况下,parse_line 函数很复杂,它可能会也可能不会向几个向量添加值,所以我认为让parse_line 返回多个值会使理解起来更复杂。所以我宁愿传递 vector(2) 并让parse_line 决定它是否需要向它添加新值。

【问题讨论】:

  • 游乐场链接中的代码似乎与您的问题完全无关。您是否使用了正确的链接?如果不能,请更新一下吗?
  • 编辑了指向操场的链接。我还发现,如果我使用 String 而不是 &amp;str 它不会抱怨。所以我真的不明白这是如何工作的。我会重新阅读本书的相关部分。

标签: generics vector rust lifetime borrow-checker


【解决方案1】:

变化:

fn parse_line<'a>(item: &'a str, target: &'a mut Vec<&'a str>)

收件人:

fn parse_line<'a>(item: &'a str, target: &mut Vec<&'a str>)

仅仅因为您有一个在某个生命周期内通用的函数'a,这并不意味着该函数使用的每个引用都必须具有'a 生命周期。 target 的可变借用的生命周期必须短于或等于 'a,但您不希望它相等,因为它会严重限制您的代码(而且完全没有必要),只要您从 target 的可变借用中删除 'a 注释,编译器会推断出可变借用的适当生命周期,然后代码编译:

fn parse_line<'a>(item: &'a str, target: &mut Vec<&'a str>) {
    // ... use item to compute a result
    target.push("result");
}

fn parse_file() {
    let mut target: Vec<&str> = Vec::new();
    let source: Vec<&str> = Vec::new();

    // ... fill source with strings from file

    for item in source {
        parse_line(item, &mut target);
    }
}

playground

【讨论】:

  • 好的,非常感谢。这就说得通了。所以,如果我可以用我自己的话来说,之前的错误是因为我强迫item&amp;mut target 拥有相同的生命周期,但这是错误的,因为item 只存在于循环中,而@987654334 @也在循环之外?为什么它会一次多次抱怨cannot borrow target` 是可变的?还有一些我不明白的地方。
  • @user103716 是的,我相信这是正确的。如果没有看到你的完整代码,我不能肯定地说,但简而言之:你强迫编译器找出一些生命周期 'a 这将适用于 &amp;mut targetitem 但这是一个不必要的繁重要求,因为这些变量的生命周期实际上不必相同。
  • @user103716 你告诉 rustc target 将被借用它的全部内容。由于内容必须比容器寿命更长,这意味着生命周期 'a 超过了容器的生命周期,因此 rustc 推断出满足您要求的唯一可能解决方案:考虑可变地借用 target 直到它被丢弃。这意味着第一次迭代的借用将与每个后续借用重叠,并且由于可变借用是排他性的,这是不可接受的。
猜你喜欢
  • 2023-01-10
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
  • 2018-04-21
  • 2023-04-10
  • 1970-01-01
  • 2023-04-01
  • 2023-01-15
相关资源
最近更新 更多