在 Rust 中如何借用可变与不可变?
How borrow as mutable vs immutable in Rust?
我已阅读这些文档:https://doc.rust-lang.org/rust-by-example/scope/borrow/mut.html
我也看过这个问题:()
文档帮助我理解了如何将借用声明为可变的(我认为):
let mut (part1, part2) = someTuple;
但是我还没有找到关于什么是不可变借用的明确说明。这是我的猜测:
let (part1, part2) = someTuple;
我知道这是一个超级基本的问题,但谷歌搜索让我深入解释的深处,我仍在努力在最简单的上下文中找到方向。
我如何在 Rust 中作为可变借用与不可变借用?
let x = 0;
let immutable_borrow = &x; //borrow as immutable
//to borrow as mutable the variable needs to be declared as mutable
let mut y = 1;
let mutable_borrow = &mut y; //borrow as mutable
注意 1:您可以在同一范围内借用不可变或可变变量,这意味着您不能这样做:
let mut x = 0;
let immutable_borrow = &x;
let mutable_borrow = &mut x;
为什么?
因为如果您对同一个变量有可变和不可变引用,那么该变量的数据可能会通过该可变引用发生变化,这可能会导致很多问题。
注2:你可以不可变地借用一个变量无限次,但你只能可变地借用一个变量一次。
//You can do this
let x = 0;
let x1 = &x;
let x2 = &x;
//...
//But you can't do this
let mut y = 0;
let y1 = &mut y;
let y2 = &mut y; //won't compile if you use y1 after you declare y2
为什么?
如上所述。一个可变引用可能会更改所有其他可变引用所指向的数据,而它们并不知道。这可能会导致很多问题。但是拥有多个不可变引用是可以的,因为数据不会被意外更改。
Ejdrien 的回答演示了可变借用和不可变借用之间的区别,但是它没有解决您问题中的副标题,即您正在执行借用作为 pattern matching 的一部分。
写的时候
let (mut part1, mut part2) = someTuple;
您通过移动将someTuple
的内容绑定到可变变量part1
和part2
。除非 someTuple
的内容 Copy
可用,否则变量 part1
和 part2
将成为其各自值的唯一所有者。如果您稍后尝试通过写入访问 someTuple
,例如
println!("{}", someTuple.0);
您将从借用检查器收到类似于
的编译错误
error[E0382]: borrow of moved value: `someTuple.0`
--> main.rs:6:20
|
4 | let (mut part1, mut part2) = someTuple;
| --------- value moved here
5 |
6 | println!("{}", someTuple.0);
| ^^^^^^^^^^^ value borrowed here after move
在这个特定的上下文中,有两种方法可以通知编译器我们只想借用 someTuple
的内容。第一种是 Ejdrien 描述的技术,它显式借用元组并针对结果引用执行模式匹配:
// Produce two mutable references
let (part1, part2) = &mut someTuple;
// Produce two immutable references
let (part1, part2) = &someTuple;
这种方法的问题是我们被迫以同样的方式借用一切。如果我们只想要对 someTuple.0
的可变引用,并希望将 someTuple.1
检索为副本或不可变引用怎么办?对于此处的元组示例,这似乎不是太关键,但对于更复杂的模式匹配情况,拥有这种类型的控制更为重要。
这给我们带来了第二种解决方案:绑定引用。代替上面的,我们可以写
// Produce two mutable references
let (ref mut part1, ref mut part2) = someTuple;
// Produce two immutable references
let (ref part1, ref part2) = someTuple;
在这里,我们明确说明我们希望如何在模式匹配中绑定每个变量。这里的关键是我们可以自由混合可变和不可变借用,因此以下内容也完全有效:
// Produce immutable reference and one mutable reference
let (ref part1, ref mut part2) = someTuple;
println!("{}", &someTuple.0); // Make a second immutable reference someTuple.0
*part2 = ... // Mutate someTuple.1
println!("{}", part1); // Continue using the immutable reference
如果我们将上面的内容与右侧的显式可变借用交换,由于同时存在可变和不可变引用,我们将再次从借用检查器收到错误:
let (part1, part2) = &mut someTuple;
println!("{}", &someTuple.0);
*part2 = ... // Mutate someTuple.1
println!("{}", part1);
产生
error[E0502]: cannot borrow `someTuple.0` as immutable because it is also borrowed as mutable
--> main.rs:6:20
|
4 | let (part1,part2) =&mut someTuple;
| -------------- mutable borrow occurs here
5 |
6 | println!("{}", &someTuple.0);
| ^^^^^^^^^^^^ immutable borrow occurs here
...
9 | println!("{}", part1);
| ----- mutable borrow later used here
error: aborting due to previous error
我已阅读这些文档:https://doc.rust-lang.org/rust-by-example/scope/borrow/mut.html
我也看过这个问题:(
文档帮助我理解了如何将借用声明为可变的(我认为):
let mut (part1, part2) = someTuple;
但是我还没有找到关于什么是不可变借用的明确说明。这是我的猜测:
let (part1, part2) = someTuple;
我知道这是一个超级基本的问题,但谷歌搜索让我深入解释的深处,我仍在努力在最简单的上下文中找到方向。
我如何在 Rust 中作为可变借用与不可变借用?
let x = 0;
let immutable_borrow = &x; //borrow as immutable
//to borrow as mutable the variable needs to be declared as mutable
let mut y = 1;
let mutable_borrow = &mut y; //borrow as mutable
注意 1:您可以在同一范围内借用不可变或可变变量,这意味着您不能这样做:
let mut x = 0;
let immutable_borrow = &x;
let mutable_borrow = &mut x;
为什么?
因为如果您对同一个变量有可变和不可变引用,那么该变量的数据可能会通过该可变引用发生变化,这可能会导致很多问题。
注2:你可以不可变地借用一个变量无限次,但你只能可变地借用一个变量一次。
//You can do this
let x = 0;
let x1 = &x;
let x2 = &x;
//...
//But you can't do this
let mut y = 0;
let y1 = &mut y;
let y2 = &mut y; //won't compile if you use y1 after you declare y2
为什么?
如上所述。一个可变引用可能会更改所有其他可变引用所指向的数据,而它们并不知道。这可能会导致很多问题。但是拥有多个不可变引用是可以的,因为数据不会被意外更改。
Ejdrien 的回答演示了可变借用和不可变借用之间的区别,但是它没有解决您问题中的副标题,即您正在执行借用作为 pattern matching 的一部分。
写的时候
let (mut part1, mut part2) = someTuple;
您通过移动将someTuple
的内容绑定到可变变量part1
和part2
。除非 someTuple
的内容 Copy
可用,否则变量 part1
和 part2
将成为其各自值的唯一所有者。如果您稍后尝试通过写入访问 someTuple
,例如
println!("{}", someTuple.0);
您将从借用检查器收到类似于
的编译错误error[E0382]: borrow of moved value: `someTuple.0`
--> main.rs:6:20
|
4 | let (mut part1, mut part2) = someTuple;
| --------- value moved here
5 |
6 | println!("{}", someTuple.0);
| ^^^^^^^^^^^ value borrowed here after move
在这个特定的上下文中,有两种方法可以通知编译器我们只想借用 someTuple
的内容。第一种是 Ejdrien 描述的技术,它显式借用元组并针对结果引用执行模式匹配:
// Produce two mutable references
let (part1, part2) = &mut someTuple;
// Produce two immutable references
let (part1, part2) = &someTuple;
这种方法的问题是我们被迫以同样的方式借用一切。如果我们只想要对 someTuple.0
的可变引用,并希望将 someTuple.1
检索为副本或不可变引用怎么办?对于此处的元组示例,这似乎不是太关键,但对于更复杂的模式匹配情况,拥有这种类型的控制更为重要。
这给我们带来了第二种解决方案:绑定引用。代替上面的,我们可以写
// Produce two mutable references
let (ref mut part1, ref mut part2) = someTuple;
// Produce two immutable references
let (ref part1, ref part2) = someTuple;
在这里,我们明确说明我们希望如何在模式匹配中绑定每个变量。这里的关键是我们可以自由混合可变和不可变借用,因此以下内容也完全有效:
// Produce immutable reference and one mutable reference
let (ref part1, ref mut part2) = someTuple;
println!("{}", &someTuple.0); // Make a second immutable reference someTuple.0
*part2 = ... // Mutate someTuple.1
println!("{}", part1); // Continue using the immutable reference
如果我们将上面的内容与右侧的显式可变借用交换,由于同时存在可变和不可变引用,我们将再次从借用检查器收到错误:
let (part1, part2) = &mut someTuple;
println!("{}", &someTuple.0);
*part2 = ... // Mutate someTuple.1
println!("{}", part1);
产生
error[E0502]: cannot borrow `someTuple.0` as immutable because it is also borrowed as mutable
--> main.rs:6:20
|
4 | let (part1,part2) =&mut someTuple;
| -------------- mutable borrow occurs here
5 |
6 | println!("{}", &someTuple.0);
| ^^^^^^^^^^^^ immutable borrow occurs here
...
9 | println!("{}", part1);
| ----- mutable borrow later used here
error: aborting due to previous error