【Rust 入门学习】3.1 通用的编程概念

通用编程概念

变量与可变性

默认情况下,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可以看到变量不可直接更换数据类型。

相关文章

发表回复

您的电子邮箱地址不会被公开。