在变量名之前和“:”之后放置“mut”有什么区别?

时间:2015-02-18 15:46:54

标签: variables syntax reference rust mutable

以下是我在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>) { /* ... */ }

3 个答案:

答案 0 :(得分:51)

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: &mut T表示您有一个引用(&)值的变量,并且您可以更改(mut引用值(包括字段,如果是结构):

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

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

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

答案 1 :(得分:51)

如果您来自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采用“白名单”的方法,如果你想要一些可变的东西,你必须明确说出来。 / p>

答案 2 :(得分:2)

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

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} 表示值的内容可以改变
  • 你需要一个可变绑定来改变可变值