【问题标题】:What's the difference between placing "mut" before a variable name and after the ":"?将“mut”放在变量名之前和“:”之后有什么区别?
【发布时间】:2015-04-19 16:41:08
【问题描述】:

这是我在 Rust 文档中看到的两个函数签名:

fn modify_foo(mut foo: Box<i32>) { *foo += 1; *foo }
fn modify_foo(foo: &mut i32) { *foo += 1; *foo }

为什么mut的位置不同?

看来第一个函数也可以声明为

fn modify_foo(foo: mut Box<i32>) { /* ... */ }

【问题讨论】:

标签: variables syntax reference rust mutable


【解决方案1】:

如果您来自 C/C++,那么基本上这样想也可能会有所帮助:

// Rust          C/C++
    a: &T     == const T* const a; // can't mutate either
mut a: &T     == const T* a;       // can't mutate what is pointed to
    a: &mut T == T* const a;       // can't mutate pointer
mut a: &mut T == T* a;             // can mutate both

您会注意到它们是互为倒数的。 C/C++ 采用“黑名单”方法,如果您希望某些内容不可变,则必须明确说明,而 Rust 采用“白名单”方法,如果您希望某些内容可变,则必须明确说明。

【讨论】:

  • 这张桌子很棒。值得注意的是,&amp;mut T 引用也类似于 C 中的 T* restrict 指针:它们可能没有别名。 &amp;T 引用没有这样的约束,也没有类似于非restrict-qualified T* 指针的引用类型。
  • 我没有 C 背景,但我仍然认为这比接受的答案更好地解释(使用 cmets),有时更简单比更长更好。
【解决方案2】:

mut foo: T 表示您有一个名为foo 的变量,即T。您可以更改变量所指的内容

let mut val1 = 2;
val1 = 3; // OK

let val2 = 2;
val2 = 3; // error: re-assignment of immutable variable

这还允许您修改您拥有的结构的字段:

struct Monster { health: u8 }

let mut orc = Monster { health: 93 };
orc.health -= 54;

let goblin = Monster { health: 28 };
goblin.health += 10; // error: cannot assign to immutable field

foo: &amp;mut T 表示您有一个引用 (&amp;) 值的变量,并且您可以更改 (mut) 引用的值(包括字段,如果它是结构):

let val1 = &mut 2;
*val1 = 3; // OK

let val2 = &2;
*val2 = 3; // error: cannot assign to immutable borrowed content

请注意,&amp;mut 仅对引用有意义 - foo: mut T 不是有效语法。您还可以在有意义的情况下组合这两个限定符 (let mut a: &amp;mut T)。

【讨论】:

  • 我明白了。我想这就像在 C++ 中一样,您可以使用 int const*int *const 来实现不同的目标。
  • @Shepmaster 您可能希望在绑定上添加 mut,以便您在结构内部进行变异(如果它是结构)。
  • @BeyondSora 不要将&amp;mut Type 视为&amp;(mut Type),而是将其视为(&amp;mut) Type。关键字mut 一般不用于类型,但有一种引用类型称为&amp;mut
  • @ScottOlson 所以,你的意思是 &amp;mut 只是一个“方便”的符号,以避免引入新的关键字,但实际上它与 lhs 通常的 mut 是一个不同的概念关键字?
  • @didierc 是的。您可以将&amp;T&amp;mut T 视为Ref&lt;T&gt;RefMut&lt;T&gt;(我刚刚编造的类型)的糖。
【解决方案3】:

下面的自然语言翻译似乎让我明白了……

let x = value;
  x {binds immutably} to {immutable value}

let mut x = value;
  x {binds mutably} to {possibly mutable value}

let x = &value;
  x {binds immutably} to {a reference to} {immutable value}

let x = &mut value;
  x {binds immutably} to {a reference to} {mutable value}

let mut x = &value;
  x {binds mutably} to {a reference to} {immutable value}

let mut x = &mut value;
  x {binds mutably} to {a reference to} {mutable value}

在哪里

  • {binds mutably} 表示绑定可以重新分配
  • {mutable value} 表示值的内容可以改变
  • 为了能够改变一个值,您需要一个可变绑定和一个可变值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多