将“mut”放在变量名之前和“:”之后有啥区别?
Posted
技术标签:
【中文标题】将“mut”放在变量名之前和“:”之后有啥区别?【英文标题】:What's the difference between placing "mut" before a variable name and after the ":"?将“mut”放在变量名之前和“:”之后有什么区别? 【发布时间】:2015-04-19 16:41:08 【问题描述】:这是我在 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>) /* ... */
【问题讨论】:
对于C++程序员:区别类似于pointerconst
vs pointee
const。
【参考方案1】:
如果您来自 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
引用也类似于 C 中的 T* restrict
指针:它们可能没有别名。 &T
引用没有这样的约束,也没有类似于非restrict
-qualified T*
指针的引用类型。
我没有 C 背景,但我仍然认为这比接受的答案更好地解释(使用 cmets),有时更简单比更长更好。【参考方案2】:
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++ 中一样,您可以使用int const*
与 int *const
来实现不同的目标。
@Shepmaster 您可能希望在绑定上添加 mut
,以便您在结构内部进行变异(如果它是结构)。
@BeyondSora 不要将&mut Type
视为&(mut Type)
,而是将其视为(&mut) Type
。关键字mut
一般不用于类型,但有一种引用类型称为&mut
。
@ScottOlson 所以,你的意思是 &mut
只是一个“方便”的符号,以避免引入新的关键字,但实际上它与 lhs 通常的 mut
是一个不同的概念关键字?
@didierc 是的。您可以将&T
和&mut T
视为Ref<T>
和RefMut<T>
(我刚刚编造的类型)的糖。【参考方案3】:
下面的自然语言翻译似乎让我明白了……
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
表示值的内容可以改变
为了能够改变一个值,您需要一个可变绑定和一个可变值
【讨论】:
以上是关于将“mut”放在变量名之前和“:”之后有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章