提问人:Jimmy Lu 提问时间:2/18/2015 最后编辑:Peter HallJimmy Lu 更新时间:12/12/2022 访问量:22014
将“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
评论
int const*
int *const
mut
&mut Type
&(mut Type)
(&mut) Type
mut
&mut
&mut
mut
&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
&T
restrict
T*
以下自然语言翻译似乎为我澄清了事情......
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}
where
{binds mutably}
means the binding can be reassigned{mutable value}
means the value's contents can change- To be able to mutate a value you need both a mutable binding and a mutable value
Note:
参考可变性与目标可变性
引用变量(如 中 )是独立于它所指向的目标变量的变量。特别是,在堆栈上有自己的位置和可变性权限。因此,如果像这里一样是不可变的,那么它就不能被重新赋值以指向其他变量。该限制与通过它改变目标的能力是分开的,如 ;目标是一个具有自身可变性权限的不同变量。但是,如果 是可变的,如 ,那么它确实可以重新赋值以指向其他一些类似类型的变量:。x
let x = &mut y
y
x
x
*x = some_value
w
let mut w = &mut p
w = &mut z
评论
value
是一个位置。位置内容是可变的。它目前包含 . 是堆栈上的一个位置。位置内容是不可变的。它当前包含的地址为 。地址类型允许更改该位置内容。因此,虽然你不能改变,但你可以改变它所指的内容。这些约束是在编译时施加的,以防止某些代码,特别是变量在具有可变引用时将不可用:一次只能有一个对变量的可变引用。4
x
value
x
*x
safe rust
value
x
let x = &mut y
x
y
let mut x = &mut y
x = &mut z
引用类型的可变变量
当你有
let mut x: &T = value;
这意味着 是引用 的实例的变量,就好像将实例的内存地址存储在 的值中一样。这个引用(即“内存地址”)是这个上下文中可变性的主题:可以修改为引用一个不同的实例,如下所示:x
T
T
x
x
T
x = some_other_T_instance;
但是引用对象(即引用的实例的值)不能通过以下方式更改:T
x
x
// Illegal
*x = a_different_value;
可变引用类型的不可变变量
当你有
let x: &mut T = value;
这意味着 that 是一个变量,它引用了 的可变实例。在这种情况下,所指对象(即实际值)是可变性的主体。可以通过这样的引用进行修改x
T
*x = some_other_value;
但是引用本身(即变量中的“内存地址”)不能:x
// illegal
x = a_different_value;
评论
常量
与指
针常量。