这是我在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 ++采用“黑名单”方法,如果你想要某些东西是不可变的,你必须明确地说,而Rust采用“白名单”方法,如果你想要一些可变的东西,你必须明确说出来。