读Rust By Example(4)

变量绑定

Rust通过静态类型确保类型安全。变量绑定能在声明的时候直接指定类型。大多数时候,编译器能够从上下文中推测变量的类型,极大的减轻了指定类型的压力。

使用 let 绑定,使值绑定到变量。

样例:

fn main() {  
    let an_integer = 1u32;
    let a_boolean = true;
    let unit = ();

    // 将 `an_integer` 复制到 `copied_integer`
    let copied_integer = an_integer;

    println!("An integer: {:?}", copied_integer);
    println!("A boolean: {:?}", a_boolean);
    println!("Meet the unit value: {:?}", unit);

    // 编译器会提示未使用的变量绑定的警告
    // 在变量前加一个下划线可以忽略此警告
    let _unused_variable = 3u32;

    let _noisy_unused_variable = 2u32;
}

可变变量

默认变量绑定是不可变的,但可以通过加上 mut 修饰符更改这个属性。

样例

fn main() {  
    let _immutable_binding = 1;
    let mut mutable_binding = 1;

    println!("Before mutation: {}", mutable_binding);

    // Ok
    mutable_binding += 1;

    println!("After mutation: {}", mutable_binding);

    // Error!
    // _immutable_binding += 1;
    // FIXME ^ Comment out this line
}

作用域和隐藏

变量绑定有用一个作用域,一般被约束在一个代码块内。代码块是在一个花括号 {} 内一系列语句的集合。同时,变量隐藏也是允许的。

样例

fn main() {  
    // 此个绑定在主函数内存活
    let long_lived_binding = 1;

    // 此代码块比主函数的作用域小一点
    {
        // 此绑定只能在这个代码块内存在
        let short_lived_binding = 2;

        println!("inner short: {}", short_lived_binding);

        // 这个绑定隐藏了外部的变量
        let long_lived_binding = 5_f32;

        println!("inner long: {}", long_lived_binding);
    }

    // Error! `short_lived_binding` doesn't exist in this scope
    //println!("outer short: {}", short_lived_binding);
    // FIXME ^ Comment out this line

    println!("outer long: {}", long_lived_binding);

    // 此绑定也隐藏了先前的变量
    let long_lived_binding = 'a';

    println!("outer long: {}", long_lived_binding);
}

变量先声明

可以先声明变量,再对其初始化。不过这种形式很少用,会导致使用未初始化的变量。

样例

fn main() {  
    // 声明变量绑定
    let a_binding;
    {
        let x = 2;
        // 初始化绑定
        a_binding = x * x;
    }

    println!("a binding: {}", a_binding);

    let another_binding;

    // Error! Use of uninitialized binding
    // println!("another binding: {}", another_binding);
    // FIXME ^ Comment out this line

    another_binding = 1;

    println!("another binding: {}", another_binding);
}

编译器禁止使用未初始化的变量,可能会导致未定义的行为。