Rust变量

一、变量声明
编程语言基本上都离不开变量的使用,Rust也不例外。Rust的变量遵循先声明后使用的原则,类型没有“默认构造函数”,变量没有“默认值”,变量如果没有显式赋值,它就没有被初始化,编译器禁止使用未经初始化的变量,因为这会产生未定义行为。

和许多现有的编程语言一样,Rust变量必须由数字、字母、下划线组成,且不能以数字开头。Rust里面的下划线是一个特殊的标识符,在编译器内部它是被特殊处理的。它跟其他标识符有许多重要区别,下划线表达的含义是“忽略这个变量绑定,后面不会再用到了”。

对于局部变量,最常见的声明语为:let var : i32 = 1;

Rust的变量声明语法有以下特点:

  1. 局部变量声明一定是以关键字let开头,类型一定是跟在冒号:的后面。这样设计语法歧义更少,语法分析器更容易编写。
  2. 声明的变量前置,对它的类型描述后置。因为在变量声明语句中,最重要的是变量本身,而类型其实是个附属的额外描述,并非必不可少的部分。如果我们可以通过上下文环境由编译器自动分析出这个变量的类型,那么这个类型描述完全可以省略不写。这也是出于类型自动推导功能的考虑。
  3. let语句不光是局部变量声明语句,而且具有模式解构的功能。

以下是简单的代码样例:

fn main() {
    let a: i32 = 1;
    println!("{}", a);

    // 变量b未显示声明初始化,使用报错
    // println!("{}", b);

    let _ = "hello";
    // _ 是特殊的变量,表示“忽略这个变量绑定,后面不会再用到了”
    // println!("{}", _);
}

二、变量绑定
在Rust中,一般把声明的局部变量并初始化的语句称为“变量绑定”
Rust中声明变量缺省是“只读”的,不可变的。如果我们需要让变量是可写的,那么需要使用mut关键字进行修饰。

以下是简单代码样例:

fn main() {
    let _immutable_binding = 1; // 默认变量绑定,不可变
    let mut mutable_binding = 1; //使用mut修饰符,变量可变

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

    mutable_binding = 5; // 可变变量可以修改
                         // _immutable_binding = 3; // 默认变量只读,不可变

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

三、变量作用域和遮蔽
变量绑定有一个作用域,它被限定只在一个代码块中。 代码块是一个被 {} 包围的语句集合。

Rust允许在同一个代码块中声明同样名字的变量。如果这样做,后面声明的变量会将前面声明的变量“遮蔽”起来,这就叫变量的遮蔽。

以下是简单的代码样例:

fn main() {
    // 此绑定生存于 main 函数中
    let long_lived_binding = 1;

    // 这是一个代码块,比 main 函数拥有更小的作用域
    {
        // 此绑定只存在于本代码块
        let short_lived_binding = 2;

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

        let short_lived_binding = 'b';

        println!(
            "inner of short_lived_binding after rebind: {}",
            short_lived_binding
        );

        // 此绑定遮蔽了外面的绑定的long_lived_binding
        let long_lived_binding = 5_f32;

        println!("inner of long_lived_binding: {}", long_lived_binding);
    }
    // 代码块结束,short_lived_binding变量作用域结束

    // 报错!`short_lived_binding` 在此作用域上不存在
    // println!("outer short: {}", short_lived_binding);

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

    // 此绑定遮蔽了前面的long_lived_binding绑定
    let long_lived_binding = 'a';

    println!(
        "outer of long_lived_binding after rebind : {}",
        long_lived_binding
    );
}

四、静态变量
Rust中可以用static关键字声明静态变量:static GLOBAL: i32 = 0;

与let语句一样,static语句同样也是一个模式匹配。与let语句不同的是,用static声明的变量的生命周期是整个程序,从启动到退出。static变量的生命周期永远是’static,它占用的内存空间也不会在执行过程中回收。这也是Rust中唯一的声明全局变量的方法。

为了保证内存安全,全局变量有以下限制:

  1. 全局变量必须在声明的时候马上初始化。
  2. 全局变量的初始化必须是编译期可确定的常量,不能包括执行期才能确定的表达式、语句和函数调用。
  3. 带有mut修饰的全局变量,在使用的时候必须使用unsafe关键字。

以下是简单代码样例:

fn main() {
    //局部变量声明,可以留待后面初始化,只要保证使用前已经初始化即可
    let x: i32 = 2;
    println!("x : {} ", x);
    //全局变量必须声明的时候初始化,因为全局变量可以写到函数外面,被任意一个函数使用
    static G1: i32 = 3;
    println!("G1 : {}", G1);
    //可变全局变量无论读写都必须用 unsafe修饰
    static mut G2: i32 = 4;
    unsafe {
        G2 = 5;
        println!("G2 : {}", G2);
    }
    // 未使用unsafe关键字引用可变全局变量,编译报错
    /*{
        G2 = 5;
        println!("G2 : {}", G2);
    }*/
    //全局变量的内存不是分配在当前函数栈上,函数退出的时候,并不会销毁全局变量占用的内存空间,程序退出才会回收
}

你可能感兴趣的:(#,《通过例子学,Rust》,rust,开发语言)