fn main() {
let mut a = String::from("a");
let closure = || {
a.push_str("b");
};
closure();
}
Run Code Online (Sandbox Code Playgroud)
这不会编译:
error[E0596]: cannot borrow immutable local variable `closure` as mutable
--> src/main.rs:7:5
|
3 | let closure = || {
| ------- consider changing this to `mut closure`
...
7 | closure();
| ^^^^^^^ cannot borrow mutably
Run Code Online (Sandbox Code Playgroud)
如果我a在闭包中返回而不添加mut,则可以编译:
fn main() {
let mut a = String::from("a");
let closure = || {
a.push_str("b");
a
};
closure();
}
Run Code Online (Sandbox Code Playgroud)
这让我很困惑.似乎在我打电话的时候closure(),closure如果里面的东西是可变的,就会被借用.我回来后为什么不借用a呢?
Mat*_* M. 11
有3个功能性状的防锈:Fn,FnMut和FnOnce.向后走:
FnOnce 只保证值可以调用一次,FnMut 只保证在可变的情况下可以调用该值,Fn 保证可以多次调用该值,并且不会发生变化.闭包将自动实现这些特征,具体取决于它捕获的内容以及它如何使用它.默认情况下,编译器将选择限制性最小的特征; 如此偏爱Fn一遍FnMut又FnMut一遍FnOnce.
在你的第二种情况:
let mut a = String::from("a");
let closure = || {
a.push_str("b");
a
};
Run Code Online (Sandbox Code Playgroud)
这种关闭需要能够返回a,这需要FnOnce.它a进入捕获.如果你试图第二次调用你的闭包,它将无法编译.如果您尝试访问a,则无法编译.
这就是FnOnce"最后手段"实施的原因.
另一方面,你的第一个案例:
let mut a = String::from("a");
let closure = || {
a.push_str("b");
};
Run Code Online (Sandbox Code Playgroud)
最多需要一个可变引用a,因此通过可变引用进行捕获.由于它捕获了一个可变引用,因此闭包实现FnMut,因此只有在它本身是可变的时才能被调用.
如果你删除mut,a编译器会向你发出信号,它需要a可变地借用.
在closure您尝试调用它之前,编译器不要求它本身可变地声明; 毕竟你可以通过值将它传递给函数而不调用它(你自己),在这种情况下mut将是多余的.
| 归档时间: |
|
| 查看次数: |
571 次 |
| 最近记录: |