【譯】理解Rust中的局部移動

原文標題: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

局部移動(Partial Moves)

目前爲止,我已經看到了一次性移動(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是一門至關酷的語言,可是仍然有不少微妙的特性。但願這篇文章能夠幫助解答其中的一個困惑。

相關文章
相關標籤/搜索