mut a:&T 和a:&mut T的区别

mut a:&T 和a:&mut T的区别
公众号: Rust碎碎念
17 人赞同了该文章
概述

话说 StackOverflow 上有个哥们问了一个问题,正如标题所述,它问的是下面这段代码里:

fn modify_foo(mut foo: Box<i32>) { *foo += 1; *foo }
fn modify_foo(foo: &mut i32) { *foo += 1; *foo }

代码里的mut放在 mut foo: Box和foo: &mut i32 的区别是什么?

mut a:&T

先来看 mut a : T和mut a : &T的区别,这个应该比较简明,即前者中a是T类型变量的可变绑定,后者中a是T类型不可变引用的可变绑定。(如果对引用的概念还比较模糊,可以参考公众号中翻译的一篇文章:《Rust 中的引用》)
下面来看个例子:

struct FullName{
    first_name:String,
    last_name:String,
}

// mut a:& T
let mut a = & FullName {
    first_name: String::from("Jobs"),
    last_name: String::from("Steve"),
};
//a重新绑定到一个新的FullName的引用
a = &FullName {
    first_name: String::from("Gates"),
    last_name: String::from("Bill"),
};
//不允许对a指向的内容作出修改
//a.first_name = String::from("Error");
println!("{}:{}",a.last_name, a.first_name);

这里的a是可变的,意思是a可以重新绑定另一个结构体的引用,但是不能对结构体里的内容作修改(比如这里对 a.first_name 的赋值就是不允许的),因为引用(&T)是不可变的。

a:&mut T

接着看下面这个例子:

// a:&mut T
let a = &mut FullName {
    first_name: String::from("Jobs"),
    last_name: String::from("Steve"),
};
//a不允许重新绑定到一个新的FullName的引用
// a = &FullName {
//     first_name: String::from("Gates"),
//     last_name: String::from("Bill"),
// };
//允许对a指向的内容作出修改
a.first_name = String::from("Gates");
println!("{}:{}",a.last_name, a.first_name);

这里的 a 绑定到了FullName的可变引用,也就是说可以对FullName进行修改,但是a是不可以修改的,即通过a修改FullName里的字段,如first_name是没问题的,但是如果要a重新绑定到新的结构体(相当于修改a)是不行的。

参考资料

https://stackoverflow.com/questions/28587698/whats-the-difference-between-placing-mut-before-a-variable-name-and-after-the
https://stackoverflow.com/questions/29672373/what-is-difference-between-mut-a-t-and-a-mut-t

关于最后的可变性:
let v = vec![0];// 变量和内部元素不可变
let mut v = vec![0];// 变量和内部元素均可变

除了这两种,还有:
let v = &mut vec![0];// 变量不可变,内部元素可变
let mut v = &vec![0];// 变量可变,内部元素不可变

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值