let a = 23;
a = 34; // wrong
struct Person {
age: i32,
name: String,
}
let p = Person { age: 32, name: "dj".to_string() };
p.age = 34; // wrong,结构体字段不允许修改
p = Person { age: 56, name: "dj".to_string() }; // 变量不可重新绑定
let vector = vec![1,2,3];
vector[0] = 2;
可变
let mut 变量绑定就是可变,可变有两层
变量本身可重新绑定
若是 struct 类型,其中的字段也允许改变
非引用类型,若是 let mut 绑定则任何改动都是允许的
let mut b = 34;
b = 65;
struct Person {
age: i32,
name: String,
};
let mut p1 = Person { age: 23, name: "dj".to_string() };
p1.age = 56;
assert_eq!(p1.age, 56);
p1 = Person { age: 34, name: "dj".to_string() };
let mut vector = vec![1,2,3];
vector[0] = 2;
assert_eq!(vector[0], 2);
彩蛋示例中我们也可以看出来,rust 是支持变量重新声明的
引用类型
我们分两步
基本数据类型的引用以及不包含引用的 strcut 类型的引用
不可变引用:变量持有者无法修改被引用对象
声明不可变引用
let a = 34;
let b = &a;
println!("{}", b); // 我们可以打印 b
*b = 45; // wrong 不可以改变引用对象
struct Person {
age: i32,
name: String,
};
let p1 = Person { age: 23, name: "dj".to_string() }; // 声明并绑定 p1 变量,资源持有者
let p2 = &p1;
p1.age = 34; // wrong 不能修改引用对象
let mut d = 45;
let b = &d; // 这里可以看出,可变绑定可以作为不可变引用,反之不可
如上: b 的类型就是不可变引用,还得在不可变的两层含义么?此时就更明显了。b 的类型是 &i32, b 的引用对象我们不能改变。再看 b 本身,他的声明是 不可变绑定,意味着 b 本身也不可重新绑定。
可变引用:变量持有者可以修引用对象
声明可变引用
被引用对象必须是可变的
let a = 34;
let b = &mut a; // wrong a 是不可变的
let mut c = 45;
let b = &mut c; // 正确
*b = 23 + 34;
assert_eq!(c, 57); // c === 57
let mut d = 34;
b = &mut d; // wrong
那么 b 的类型就是变引用,还得在不可变的两层含义么?此时就更明显了。b 的类型是 &mut i32, b 的引用对象我可以修改。但是再看 b 本身,他的声明是 不可变绑定,意味着 b 本身也不可重新绑定。
包含引用类型的 struct
不可变复合类型包含可变引用
struct Man<'a> {
age: &mut 'a i32,
name: String,
}
let mut age = 34;
let man = Man { age: &mut age, name: "dj".to_string() };
// man = Man { age: &mut age, name: "dj2".to_string() }; // man 不可重新赋值
// man.age = &mut age; // man 的字段不可重新赋值
*man.age = 354;
这个例子是一个包含引用的结构体,他包含了可变引用。可以看到我们声明的变量 man, man 本身以及字段都是不可重新赋值的,但是由于 age 字段是可变引用,所以 man 的 age 是可以修改的。此时的 age 就好比是 let age: &mut i32 = &mut a
示例
非引用类型
不可变
可变
引用类型
基本数据类型的引用以及不包含引用的 strcut 类型的引用
不可变引用:变量持有者无法修改被引用对象
如上: b 的类型就是不可变引用,还得在
不可变
的两层含义么?此时就更明显了。b 的类型是&i32
, b 的引用对象我们不能改变。再看 b 本身,他的声明是不可变绑定
,意味着 b 本身也不可重新绑定。可变引用:变量持有者可以修引用对象
声明可变引用
那么 b 的类型就是变引用,还得在
不可变
的两层含义么?此时就更明显了。b 的类型是&mut i32
, b 的引用对象我可以修改。但是再看 b 本身,他的声明是不可变绑定
,意味着 b 本身也不可重新绑定。包含引用类型的 struct
不可变复合类型包含可变引用
这个例子是一个包含引用的结构体,他包含了可变引用。可以看到我们声明的变量 man, man 本身以及字段都是不可重新赋值的,但是由于 age 字段是可变引用,所以 man 的 age 是可以修改的。此时的 age 就好比是
let age: &mut i32 = &mut a
可变复合类型包含不可变引用
从这个例子我们又可以得到一个彩蛋,可变类型是可以赋值给不可变类型的
woman.age = &mut age2
多级引用
总结
对于 rust 的可变与不可变要有针对性的看待,不是声明为可变类型就代表一定可变。对于基本类型是的,但对于复合类型就要看复合类型本身是否包含引用类型。
对于基本类型
对于复合类型
可变引用可以赋值给不可变引用,反之不行。这也是情理之中的,既然知道他是不可变,那赋值给他也没事儿。(但真的没事儿么?)```