原文標題:Understanding Partial Moves in Rust
原文連接:https://whileydave.com/2020/11/30/understanding-partial-moves-in-rust/
公衆號: Rust 碎碎念
翻譯 by: Prayingweb
最近,我一直在研究Rust,雖然從不少方面來看它都是一門十分優秀的語言,但我也發現了不少不易察覺的複雜性。其中一個例子就是,不太引人注意的局部移動(partial move) 。所以,我在想,爲何不寫一篇文章來介紹它呢?編輯器
我不許備在這裏介紹Rust中全部權和借用的所有細節。不過,這裏咱們仍然須要一些背景知識使得局部移動(partial move)可以講得通。下面經過是一個box和一個箭頭頭來表示Rust中的全部權!
flex
在一個沒有全部權的世界裏(想一想Java、C/C++),咱們能夠經過別名(aliasing)毫無限制地引用數據。咱們可讓兩個引用指向相同的數據,數據之間互相引用等等。ui
在全部權的世界裏(即Rust),一個引用能夠擁有它所指向的數據。在這種狀況下,不容許再有對該數據的持有全部權的其餘引用(owning references)。例如,若是兩個引用指向相同的數據(即上圖中中間的狀況),只有一個引用能夠是全部者。
url
這種對關聯全部權的引用的限制影響了咱們寫程序的方式。假定咱們試圖從變量p
拷貝一份持有全部權的引用到變量q
:spa
這就行不通了,由於它破壞了全部權的不變性 。若是容許這種狀況,咱們將會對同一份數據持有兩個帶有全部權的引用,而這是不被容許的。因此,咱們該怎麼辦呢?咱們能夠移動(move)它 。翻譯
在上圖中,變量
p
的值通過移動(move)操做後已經做廢,在對p
賦予新的值以前,咱們不能再使用它了。固然,這也對咱們使用Rust編寫程序產生了至關大的影響。可是,我不許備在這裏討論這個問題。code
目前爲止,我已經看到了一次性移動(move)整個變量(例如,上面中從p
移動到q
)。此外,咱們還能夠執行一個局部移動(partial move),在局部移動(partial move)中,能夠僅移動(move)給定變量的一部份內容。假定如今咱們的變量p
是一個pair,其中每一個元素包含一個持有全部權的引用。而後,咱們能夠把p
中的第二個元素移動到另外一個變量q
中,以下圖所示:ci
這個例子的有趣之處在於,不一樣於以前的狀況,儘管變量p
的一部份內容已經失效,但它仍然能夠以一種受限的方式被使用。具體來說,咱們可使用p.0
可是不能使用p.1
。此外,Rust阻止咱們對變量p
進行整個的拷貝(copy)或移動(move)(儘管在我看來,這並無必要)。上面的示例轉爲代碼,以下:it
fn main() {
let mut x = 123;
let mut y = 456;
let mut p = (&mut x,&mut y);
let mut q = p.1;
...
}
目前爲止,一切都好。可是,當對...
進行替換, 好比替換爲let mut z = p;
時,咱們會獲得下面的錯誤信息:
error[E0382]: use of partially moved value: `p`
--> src/main.rs:6:17
|
5 | let mut q = p.1;
| --- value partially moved here
6 | let mut z = p;
| ^ value used here after partial move
只是簡單地告訴咱們,咱們不能使用一個因爲以前的移動(move)操做而已經失效的值。我的而言,我不太理解爲何Rust阻止這種移動(move)操做,由於可以很容易地推導出z
只是被部分定義(譯註:即另外一部分無效),就像它對p
所作的那樣。想必是,儘管能夠推導,可是經過某個引用對p
賦值必然會致使某些問題吧。
Rust是一門至關酷的語言,可是仍然有不少微妙的特性。但願這篇文章能夠幫助解答其中的一個困惑。