无法借用不可变,因为它在函数参数中也借来可变

这是怎么回事(操场)?


struct Number {

    num: i32

}


impl Number {

    fn set(&mut self, new_num: i32) {

        self.num = new_num;

    }

    fn get(&self) -> i32 {

        self.num

    }

}


fn main() {

    let mut n = Number{ num: 0 };

    n.set(n.get() + 1);

}

给出此错误:


error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable

  --> <anon>:17:11

   |

17 |     n.set(n.get() + 1);

   |     -     ^          - mutable borrow ends here

   |     |     |

   |     |     immutable borrow occurs here

   |     mutable borrow occurs here

但是,如果您只是简单地将代码更改为此:


fn main() {

    let mut n = Number{ num: 0 };

    let tmp = n.get() + 1;

    n.set(tmp);

}

对我来说,这些看起来完全等效-我的意思是,我希望前者在编译时会转换为后者。Rust不会在评估下一级函数调用之前评估所有函数参数吗?


交互式爱情
浏览 830回答 1
1回答

慕尼黑的夜晚无繁华

这行:n.set(n.get() + 1);被减为Number::set(&mut n, n.get() + 1);现在,错误消息可能会更加清楚:error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable&nbsp; --> <anon>:18:25&nbsp; &nbsp;|18 |&nbsp; &nbsp; &nbsp;Number::set(&mut n, n.get() + 1);&nbsp; &nbsp;|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&nbsp; ^&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - mutable borrow ends here&nbsp; &nbsp;|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; |&nbsp; &nbsp;|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; immutable borrow occurs here&nbsp; &nbsp;|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mutable borrow occurs here当Rust从左到右评估参数时,该代码与此等效:let arg1 = &mut n;let arg2 = n.get() + 1;Number::set(arg1, arg2);现在应该很明显出了什么问题。交换前两行即可解决此问题,但Rust不会进行这种控制流分析。它最初是作为Bug#6268创建的,现在已集成到RFC 2094(非词法生存期)中。如果您使用Rust 2018,则会自动启用NLL,并且您的代码现在将编译而不会出现错误。
打开App,查看更多内容
随时随地看视频慕课网APP