gpt4 book ai didi

loops - 在具有生命周期边界的递归函数内的循环中借用检查器错误

转载 作者:行者123 更新时间:2023-11-29 08:07:28 26 4
gpt4 key购买 nike

为什么借用检查器会提示此代码?

fn foo<'a>(v: &mut Vec<&'a str>, buf: &'a mut String) {
loop {
foo(v, buf);
}
}
error[E0499]: cannot borrow `*buf` as mutable more than once at a time
--> src/main.rs:3:16
|
3 | foo(v, buf);
| ^^^ mutable borrow starts here in previous iteration of loop
4 | }
5 | }
| - mutable borrow ends here

如果我删除生命周期限制,代码编译正常。

fn foo(v: &mut Vec<&str>, buf: &mut String) {
loop {
foo(v, buf);
}
}

这不是 Mutable borrow in a loop 的副本,因为在我的例子中没有返回值。


我很确定我的最终目标无法在安全的 Rust 中实现,但现在我想更好地了解借用检查器的工作原理,但我不明白为什么在参数之间添加生命周期限制会延长借用这段代码。

最佳答案

具有显式生命周期 'a 的版本将 Vec 的生命周期与 buf 的生命周期联系起来。当 VecString 被重新借用时,这会导致麻烦。在循环中将参数传递给 foo 时会发生重新借用:

fn foo<'a>(v: &mut Vec<&'a str>, buf: &'a mut String) {
loop {
foo(&mut *v, &mut *buf);
}
}

这是由编译器隐式完成的,以防止在循环中调用 foo 时使用参数。如果实际移动了参数,则在第一次递归调用 foo 之后,它们将无法再使用(例如,对 foo 的连续调用)。

强制 buf 移动可以解决错误:

fn foo<'a>(v: &mut Vec<&'a str>, buf: &'a mut String) {
foo_recursive(v, buf);
}

fn foo_recursive<'a>(v: &mut Vec<&'a str>, buf: &'a mut String) -> &'a mut String{
let mut buf_temp = buf;
loop {
let buf_loop = buf_temp;
buf_temp = foo_recursive(v, buf_loop);
// some break condition
}
buf_temp
}

但是,一旦您尝试实际使用 buf,事情就会再次崩溃。这是您的示例的精简版本,展示了为什么编译器禁止 buf 的连续可变借用:

fn foo<'a>(v: &mut Vec<&'a str>, buf: &'a mut String) {
bar(v, buf);
bar(v, buf);
}

fn bar<'a>(v: &mut Vec<&'a str>, buf: &'a mut String) {
if v.is_empty() {
// first call: push slice referencing "A" into 'v'
v.push(&buf[0..1]);
} else {
// second call: remove "A" while 'v' is still holding a reference to it - not allowed
buf.clear();
}
}

fn main() {
foo(&mut vec![], &mut String::from("A"));
}

在您的示例中,对 bar 的调用等同于对 foo 的递归调用。编译器再次提示 *buf 不能被多次借用为可变的。提供的 bar 实现显示 bar 上的生命周期规范将允许以 v 进入无效状态的方式实现此功能.编译器通过单独查看 bar 的签名来理解来自 buf 的数据可能会流入 v 并拒绝代码,因为它可能不安全,而不管bar 的实际实现。

关于loops - 在具有生命周期边界的递归函数内的循环中借用检查器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51505176/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com