原文标题: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是一门至关酷的语言,可是仍然有不少微妙的特性。但愿这篇文章能够帮助解答其中的一个困惑。