这是我在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>) { /* ... */ }
Answers:
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
在有意义的情况下结合使用两个限定符()。
int const*
vs.int *const
实现不同的目标。
mut
在绑定上添加它,以允许您在结构内部进行突变(如果它是结构)。
&mut Type
作为&(mut Type)
,而是作为(&mut) Type
。关键字mut
通常不在类型中使用,但是有一种称为的引用类型&mut
。
const
字段。这是安全的,因为Rust保证您可以进行某些突变,其他任何人都不能同时对其进行读取或突变。
&T
和&mut T
作为糖Ref<T>
和RefMut<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采用“白名单”方法,其中,如果希望某些事物是易变的,则必须如此明确地说。
&mut T
引用也类似于T* restrict
C中的指针:它们可能没有别名。&T
引用没有这种约束,并且没有类似于非restrict
限定T*
指针的引用类型。
const
vspointee
常量。