通用编程概念
变量与可变性
默认情况下,Rust中变量是不可改变的,这是因为Rust提出的安全性和简单并发性的编程理念。当然,Rust也提供了如何使用可变变量的方法。
在项目目录中生成一个名为variables的新项目来做测试,使用 cargo new variables
。
cd ~/projects/ cargo new variables cd variables/
在新项目的主函数中,写入如下代码,用来验证变量的不变性。
文件名:src/main.rs
fn main() { let x = 5; println!("变量 x 为:{x}"); x = 10; println!("变量 x 为:{x}"); }
保存并运行,会收到一个报错。
$ cargo run Compiling variables v0.1.0 (/home/mshing/projects/variables) error[E0384]: cannot assign twice to immutable variable `x` --> src/main.rs:4:5 | 2 | let x = 5; | - | | | first assignment to `x` | help: consider making this binding mutable: `mut x` 3 | println!("变量 x 为:{x}"); 4 | x = 10; | ^^^^^^ cannot assign twice to immutable variable For more information about this error, try `rustc --explain E0384`. error: could not compile `variables` due to previous error
这个例子展示了编译器帮助我们定位程序错误,这不可怕,可怕的是程序没有抛出任何错误,却得不到自己想要的结果。
这里很明显的看到:cannot assign twice to immutable variable。
不能对不可变变量进行二次赋值,这是我们需要去修改的地方。
Rust 默认申明变量是不可变变量,为了得到可变变量需要在关键字前面添加mut来使其可变。
继续修改文件内容
文件名:src/main.rs
fn main() { let mut x = 5; println!("变量 x 为:{x}"); x = 10; println!("变量 x 为:{x}"); }
再次运行程序:
$ cargo run Compiling variables v0.1.0 (/home/mshing/projects/variables) Finished dev [unoptimized + debuginfo] target(s) in 1.47s Running `target/debug/variables` 变量 x 为:5 变量 x 为:10
常量
在之前提到不可变变量的时候,有些疑惑,这不就是一个常量吗?不可变变量和常量一样,绑定到常量的值是无法修改的。但是还是会有一些差别,常量是不允许使用 mut 关键字的,常量默认不可改变且总不可改变。
其次,需要使用 const 关键字而不是 let 来关键字来声明一个常量。在声明的同时还得明确标注值的类型。
常量声明例子:
fn main() { const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3; const MAX_POINTS: u32 = 100_100; println!("{THREE_HOURS_IN_SECONDS},{MAX_POINTS}") }
常量在整个程序间共享。
运行:
$ cargo run Compiling variables v0.1.0 (/home/mshing/projects/variables) Finished dev [unoptimized + debuginfo] target(s) in 3.24s Running `target/debug/variables` 10800,100100
变量隐藏性
声明一个与之前声明的同名新变量的时候,第一个变量会被第二个变量隐藏了,或者说是覆盖了。在之后的我们使用这个变量名字的时候,他会指向第二个变量。还可以重复使用let 关键字并使用相同的名字来不断隐藏变量:
文件名:src/main.rs
fn main() { let x = 5; println!("首次变量值:{x}"); let x = x + 1; println!("第二次变量值:{x}"); { let x = x * 2; println!("局部改变:{x}"); } println!("最后变量值:{x}"); }
运行:
$ cargo run Compiling variables v0.1.0 (/home/mshing/projects/variables) Finished dev [unoptimized + debuginfo] target(s) in 0.42s Running `target/debug/variables` 首次变量值:5 第二次变量值:6 局部改变:12 最后变量值:6
变量隐藏机制和 mut 不可同时使用否则会报错。因为重复使用 let 关键字会创建出新的变量,所以我们可以在复用变量名称的同事改变他的类型。
例子1 不使用 mut :
文件名:src/main.rs
fn main() { let x = "mshing"; println!("{x}"); let x = x.len(); println!("{x}"); }
运行:
$ cargo run Compiling variables v0.1.0 (/home/mshing/projects/variables) Finished dev [unoptimized + debuginfo] target(s) in 0.36s Running `target/debug/variables` mshing 6
例子2 使用 mut :
文件名:src/main.rs
fn main() { let mut x = "mshing"; println!("{x}"); let x = x.len(); println!("{x}"); }
运行:
$ cargo run Compiling variables v0.1.0 (/home/mshing/projects/variables) warning: variable does not need to be mutable --> src/main.rs:2:9 | 2 | let mut x = "mshing"; | ----^ | | | help: remove this `mut` | = note: `#[warn(unused_mut)]` on by default warning: `variables` (bin "variables") generated 1 warning Finished dev [unoptimized + debuginfo] target(s) in 0.34s Running `target/debug/variables` mshing 6
例子3 使用 mut ,改变变量类型:
文件名:src/main.rs
fn main() { let mut x = "mshing"; println!("{x}"); x = x.len(); println!("{x}"); }
运行:
$ cargo run Compiling variables v0.1.0 (/home/mshing/projects/variables) error[E0308]: mismatched types --> src/main.rs:4:9 | 2 | let mut x = "mshing"; | -------- expected due to this value 3 | println!("{x}"); 4 | x = x.len(); | ^^^^^^^ expected `&str`, found `usize` For more information about this error, try `rustc --explain E0308`. error: could not compile `variables` due to previous error
例子1、例子2,可以通过 let 直接改变变量的类型。例子3可以看到变量不可直接更换数据类型。