# 3.1 变量和可变性

## 3.1.1 绑定

在Rust中，将值和变量关联的过程称为绑定，变量的绑定可以使用`let`关键字，如下：

```rust
let a = 1;                 // 将1绑定到变量a
let mut b = 2;             // 将2绑定到变量b
let some_number = Some(2); // 将Some(2)绑定到some_number
```

## 3.1.2 变量

Rust中变量分为不可变变量和可变变量。不可变变量不能对其进行二次绑定，可变变量可以对其进行二次绑定。

- 不可变变量定义方式如下：

    ```rust
    let a: u32 = 1; // 将1绑定到a这个变量
    let b = 0u32;
    let c = 1;      // 定义时不指定类型，可以自动类型推导
    ```

    对不可变变量二次绑定一个值会报错：

    ```rust
    let a: u32 = 1; // 将1绑定到变量a，a为不可变变量，
    a = 2;          // 编译错误，a是不可变的变量，不能进行二次绑定
    ```

- 可变变量定义方式如下：

    ```rust
    let mut a: u32 = 1; // 通过mut关键字定义可变变量
    a = 2;              // 将2绑定到变量a，编译正确，因为a是可变变量，可以进行二次绑定
    let mut b = 2;
    b = 3;
    ```

> 设计思考：
> 从编译器的角度，如果一个值定义为不可变变量，那它就不会改变，更易于推导。想一下如果代码非常多，如果变量不会变化，但是允许它可变，其实会更容易滋生bug。

## 3.1.3 常量

常量是绑定到一个名称不允许改变的值，定义方式如下：

```rust
const HOUR_IN_SECONDS: u32 = 60 * 60;
```

常量和不可变变量的区别：
- 不允许对常量使用`mut`关键字，它总是不可变的，定义时必须显式地标注类型；

    ```rust
    let a = 1u32;     // 编译正确
    let a = 1;        // 编译正确

    const A: u32 = 1; // 编译正确
    const B = 2u32;   // 编译错误
    const C = 2;      // 编译错误
    ```
- 常量可以在任何作用域声明，包括全局作用域；
- 常量只能被设置为常量表达式，不能是在运行时计算出来的值。
    ```rust
    let a: u32 = 1;
    let b: u32 = 2;
    const A: u32 = a + b; // 编译错误
    ```

## 3.1.4 隐藏

Rust中可以定义一个与之前的变量同名的变量，这称之为第一个变量被第二个变量隐藏。隐藏和`mut`的区别：隐藏是定义了一个新的变量，而使用`mut`是修改原来的变量。

```rust
fn main() {
    let a: u32 = 1;         // 这个变量a被下面的a隐藏掉了
    let a: u32 = 2;         // 定义了一个新的变量，这个变量也叫作a
    println!("a: {:?}", a); // 输出结果为2

    let mut b: u32 = 1;     // 定义可变变量b
    b = 2;                  // 对b的值进行的修改
    println!("b: {:?}", b); // 输出结果为2

    let c = 5;
    {
        // 在当前的花括号作用域内，对之前的c进行隐藏
        let c = 3;
        println!("c: {:?}", c); // 输出结果为3
    } 
    println!("c: {:?}", c); // 输出结果为5
}
```

