簡體   English   中英

如何在 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 的回答展示了可變借用和不可變借用之間的區別,但是它沒有解決您問題中的副標題,即您正在執行借用作為模式匹配的一部分。

當你寫

let (mut part1, mut part2) = someTuple;

您通過移動它們將someTuple的內容someTuple到可變變量part1part2 除非someTuple的內容可以Copy ,否則變量part1part2成為它們各自值的唯一所有者。 如果您稍后嘗試通過寫入訪問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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM