当我想知道可变引用如何转移到方法中时,所有问题都开始了。
let a = &mut x;
a.somemethod(); // value of a should have moved
a.anothermethod(); // but it works.
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索了很多。(真的很多)而且我注意到作为参数传递给函数的可变引用总是会经历以下转换。(这称为再借)
fn test(&mut a) -> ();
let a = &mut x;
test(a); // what we write in code.
test(&mut *a); // the actual action in code.
Run Code Online (Sandbox Code Playgroud)
因此,我在谷歌上搜索了更多有关“再借”的详细信息。
这就是我所拥有的。
在任何代码中,x指的是任意数据。我没有提及它,因为我认为它的类型对于讨论来说并不重要。(不过,我自己用的是i32)。
let a = &mut x;
let b = &mut *a; // a isn't available from now on
*a = blahblah; // error! no more access allowed for a
*b = blahblah; // …Run Code Online (Sandbox Code Playgroud) struct Foo {
val: i32
}
impl Foo {
pub fn maybe_get(&mut self) -> Option<&mut i32> {
Some(&mut self.val)
}
pub fn definitely_get(&mut self) -> &mut i32 {
{ // Add closure to ensure things have a chance to get dropped
if let Some(val) = self.maybe_get() {
// Explicit return to avoid potential scope sharing with an else block or a match arms.
return val;
}
}
// One would think any mutable references would not longer …Run Code Online (Sandbox Code Playgroud) 以下示例代码无法编译:
fn invoke(i: i32, mut f: impl FnMut(i32)) {
f(i)
}
fn main() {
let f: fn(i32, _) = invoke;
let mut sum: i32 = 0;
for i in 0..10 {
_ = f(i, |x| sum += x);
}
println!("{:?}", sum);
}
Run Code Online (Sandbox Code Playgroud)
编译器返回以下错误:
Compiling playground v0.0.1 (/playground)
error[E0499]: cannot borrow `sum` as mutable more than once at a time
--> src/main.rs:10:18
|
10 | _ = f(i, |x| sum += x);
| - ^^^ --- borrows occur due to use …Run Code Online (Sandbox Code Playgroud) 对于 impl 块中的函数,我们使用以下语法:
fn test(&mut self) {}
Run Code Online (Sandbox Code Playgroud)
但对于普通函数,我们使用以下语法:
fn test(data: &mut u64) {}
Run Code Online (Sandbox Code Playgroud)
我理解self是变量,而Self是类型。在第一种情况下,我们使用&mut变量 ( self),但在第二种情况下,我们使用&mut类型 ( u64)。为什么会出现这种不一致的情况呢?
来自铁锈书:
在任何给定时间,您可以拥有一个可变引用或任意数量的不可变引用。
考虑以下代码:
fn main() {
let mut a = 41;
let b = &mut a;
let c: &i32 = &a; // [1]
let d: &i32 = &b;
println!("{} {}", b, c); // [2]
println!("{} {}", b, d);
}
Run Code Online (Sandbox Code Playgroud)
如果我们尝试编译我们会得到:
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
--> src\main.rs:43:19
|
42 | let b = &mut a;
| ------ mutable borrow occurs here
43 | let c: &i32 = &a; // [1] …Run Code Online (Sandbox Code Playgroud) struct C {
p: String,
q: String,
}
impl C {
fn call(&mut self) {}
}
fn main(){
let mut c = C { p: "p".to_string(), q: "q".to_string() };
let p = &mut c.p; // first mutable borrow occurs here
let q = &mut c.q; // second mutable borrow doesn't occur here, why???
c.call(); // second mutable borrow occurs here // error[E0499]: cannot borrow `c` as mutable more than once at a time
p.push('x');
q.push('y');
}
Run Code Online (Sandbox Code Playgroud)
let q = &mut …