将 "mut" 放在变量名之前和“:”之后有什么区别?
What's the difference between placing "mut" before a variable name and after the ":"?
这是我在 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>) { /* ... */ }
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
)。
如果您来自 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++ 采用 "blacklist" 方法,如果你希望某些东西不可变,你必须明确说明,而 Rust 采用 "whitelist" 方法,如果你希望某些东西可变你得这么明确地说。
下面的自然语言翻译似乎让我明白了...
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}
表示值的内容可以改变
- 为了能够改变一个值你需要一个可变绑定和一个可变值
这是我在 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>) { /* ... */ }
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
)。
如果您来自 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++ 采用 "blacklist" 方法,如果你希望某些东西不可变,你必须明确说明,而 Rust 采用 "whitelist" 方法,如果你希望某些东西可变你得这么明确地说。
下面的自然语言翻译似乎让我明白了...
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}
表示值的内容可以改变- 为了能够改变一个值你需要一个可变绑定和一个可变值