变量 1 2 3 4 5 6 let variable : i32 = 100; fn main() { let x = 5; x = 10; }
这段代码会报错,变量是只读的。mut关键字申明的变量才是可写的。
1 2 let mut x = 5; // mut x: i32 x = 10;
mut x是一个“模式”,我们还可以用这种方式同时声明多个变量
1 2 let (mut a, mut b) = (1, 2); let Point { x: ref a, y: ref b} = p;
Rust中,每个变量必须被合理初始化之后才能被使用。 编译器会帮我们做一个执行路径的静态分析,确保变量在使用前一定被初始化:
1 2 3 4 5 6 7 8 9 fn test(condition: bool) { let x: i32; // 声明 x,不必使用 mut 修饰 if condition { x = 1; // 初始化 x,不需要 x 是 mut 的,因为这是初始化,不是修改 println!("{}", x); } // 如果条件不满足,x 没有被初始化 // 但是没关系,只要这里不使用 x 就没事 }
变量遮蔽 ,这两个x代表的内存空间完全不同,类型也完全不同,它们实际上是两个不同的变量。 作用 1.在同一个函数内部把一个变量转换为另一个类型的变量,但又不想给它们起不同的名字 2. 在同一个函数内部,需要修改一个变量绑定的可变性
1 2 3 4 5 6 fn main() { let x = "hello"; println!("x is {}", x); let x = 5; println!("x is {}", x); }
1 2 3 4 5 6 7 8 9 10 11 // 注意:这段代码只是演示变量遮蔽功能,并不是Vec类型的最佳初始化方法 fn main() { let mut v = Vec::new(); // v 必须是mut修饰,因为我们需要对它写入数据 v.push(1); v.push(2); v.push(3); let v = v; // 从这里往下,v成了只读变量,可读写变量v已经被遮蔽,无法再访问 for i in &v { println!("{}", i); } }
类型推导 1 2 3 4 5 6 7 8 9 10 11 fn main() { // 没有明确标出变量的类型,但是通过字面量的后缀, // 编译器知道elem的类型为u8 let elem = 5u8; // 创建一个动态数组,数组内包含的是什么元素类型可以不写 let mut vec = Vec::new(); vec.push(elem); // 到后面调用了push函数,通过elem变量的类型, // 编译器可以推导出vec的实际类型是 Vec<u8> println!("{:? }", vec); }
类型别名 1 2 3 4 5 6 7 8 type Age = u32; fn grow(age: Age, year: u32) -> Age { age + year } fn main() { let x : Age = 20; println!("20 years later: {}", grow(x, 20)); }
使用Double的时候,就等同于(i32, Vec),可以简化代码。 type Double = (T, Vec); // 小括号包围的是一个 tuple,请参见后文中的复合数据类型
静态变量 static GLOBAL: i32 = 0; 占用的内存空间不会在程序执行期间回收 必须在声明的同时进行初始化 初始化必须是编译期可确定的常量 带有mut修饰的全局变量,在使用的时候必须使用unsafe关键字
fn main() {
//局部变量声明,可以留待后面初始化,只要保证使用前已经初始化即可
let x;
let y = 1_i32;
x = 2_i32;
println!("{} {}", x, y);
//全局变量必须声明的时候初始化,因为全局变量可以写到函数外面,被任意一个函数使用
static G1 : i32 = 3;
println!("{}", G1);
//可变全局变量无论读写都必须用 unsafe修饰
static mut G2 : i32 = 4;
unsafe {
G2 = 5;
println!("{}", G2);
}
//全局变量的内存不是分配在当前函数栈上,函数退出的时候,并不会销毁全局变量占用的内存空间,程序
退出才会回收
}
常量 const GLOBAL: i32 = 0; 不允许使用mut关键字修饰 一定要是一个编译期常量,不能是运行期的值 它与static变量的最大区别:编译器并不一定会给const常量分配内存空间,在编译过程中,它很可能会被内联优化。因此,用户千万不要用hack的方式,通过unsafe代码去修改常量的值,这么做是没有意义的。以const声明一个常量,也不具备类似let语句的模式匹配功能。