简体   繁体   English

如何在 Rust 中借用可变与不可变?

[英]How borrow as mutable vs immutable in Rust?

I've read these docs:https://doc.rust-lang.org/rust-by-example/scope/borrow/mut.html我已经阅读了这些文档:https ://doc.rust-lang.org/rust-by-example/scope/borrow/mut.html

I've also read this question: ( Cannot borrow immutable borrowed content as mutable )我也读过这个问题:( 不能将不可变的借用内容作为可变借用


The docs helped me understand how to declare borrowing as mutable (I think):这些文档帮助我理解了如何将借用声明为可变的(我认为):

let mut (part1, part2) = someTuple;

But I'm haven't been able to find explicit instructions on what borrowing as an immutable looks like.但是我一直无法找到关于什么是不可变的借用的明确说明。 This is my guess:这是我的猜测:

let (part1, part2) = someTuple;

I know this is a super basic question, but Googling it took me way off into the deep end of explanations and I'm still trying to get my bearings in the most simple of contexts.我知道这是一个非常基本的问题,但谷歌搜索让我深入到解释的深处,我仍然试图在最简单的上下文中找到我的方向。

How do I borrow as mutable vs an immutable in Rust?我如何在 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

Note 1 : you can borrow a variable either as immutable or mutable in the same scope, meaning you can't do this:注意 1 :您可以在同一范围内借用一个变量作为不可变或可变的,这意味着您不能这样做:

let mut x = 0;
let immutable_borrow = &x;
let mutable_borrow = &mut x;

Why?为什么?

Because if you would have mutable and immutable references of the same variable, then the data of that variable could change through that mutable reference and that could cause a lot of problems.因为如果您有同一个变量的可变和不可变引用,那么该变量的数据可能会通过该可变引用而改变,这可能会导致很多问题。


Note 2 : you can immutably borrow a variable endless times but you can mutably borrow a variable only once.注意 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

Why?为什么?

As mentioned above.正如刚才提到的。 One mutable reference could change the data all the other mutable references are poiting to without them knowing.一个可变引用可以改变所有其他可变引用指向的数据,而他们不知道。 That could cause a lot of problems.这可能会导致很多问题。 But having multiple immutable references is okay, because the data can't be unexpectedly changed.但是有多个不可变引用是可以的,因为数据不会被意外更改。

Ejdrien answers demonstrates the difference between mutable and immutable borrows, however it does not address a subtitle in your question, which is that you are performing borrows as part of pattern matching . Ejdrien 的回答展示了可变借用和不可变借用之间的区别,但是它没有解决您问题中的副标题,即您正在执行借用作为模式匹配的一部分。

When you write当你写

let (mut part1, mut part2) = someTuple;

you are binding the contents of someTuple to the mutable variables part1 and part2 by moving them.您通过移动它们将someTuple的内容someTuple到可变变量part1part2 Unless the contents of someTuple were Copy able, the variables part1 and part2 become the exclusive owners of their respective values.除非someTuple的内容可以Copy ,否则变量part1part2成为它们各自值的唯一所有者。 If you attempt to access someTuple later by writing, eg如果您稍后尝试通过写入访问someTuple ,例如

println!("{}", someTuple.0);

you'll receive a compile error from the borrow checker that resembles你会从借用检查器收到一个编译错误,类似于

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

In this particular context, there are two ways to inform the compiler that we want to only borrow the contents of someTuple .在这个特定的上下文中,有两种方法可以通知编译器我们只想借用someTuple的内容。 The first is the technique that Ejdrien described, which is explicitly borrowing the tuple and the performing the pattern matching against then resulting reference:第一个是 Ejdrien 描述的技术,它显式地借用元组并根据结果引用执行模式匹配:

// Produce two mutable references
let (part1, part2) = &mut someTuple;

// Produce two immutable references
let (part1, part2) = &someTuple;

The problem with this approach is that we are forced to borrow everything in the same way.这种方法的问题在于我们被迫以同样的方式借用一切 What if we only want a mutable reference to someTuple.0 , and want to retrieve someTuple.1 as a copy, or as an immutable reference?如果我们只想要对someTuple.0的可变引用,并且想要检索someTuple.1作为副本或不可变引用怎么办? For the tuple example here, this may not seem too critical, but for more complex cases of pattern matching, having this type of control is much more important.对于这里的元组示例,这似乎不太重要,但对于更复杂的模式匹配情况,拥有这种类型的控制更为重要。

This brings us two the second solution: binding references.这给我们带来了第二个解决方案:绑定引用。 Instead of the above, we can write代替上面的,我们可以写

// Produce two mutable references
let (ref mut part1, ref mut part2) = someTuple;

// Produce two immutable references
let (ref part1, ref part2) = someTuple;

Here, we explicitly state how we want to bind each variable in the pattern matching.在这里,我们明确说明我们希望如何绑定模式匹配中的每个变量。 The key here is that we are free to intermix mutable and immutable borrows, so the following is also entirely valid:这里的关键是我们可以自由地混合可变和不可变借用,因此以下内容也完全有效:

// 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

If we swap the above with an explicit mutable borrow on the right hand side, we'll once again receive errors from the borrow checker due to simultaneous mutable and immutable references:如果我们用右侧的显式可变借用交换上述内容,由于同时可变和不可变引用,我们将再次从借用检查器收到错误:

let (part1, part2) = &mut someTuple;

println!("{}", &someTuple.0);
*part2 = ... // Mutate someTuple.1
println!("{}", part1);

produces产生

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM