[英]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
到可變變量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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.