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

相关文章
相关标签/搜索