RUST 学习日记 第5课 ——变量和常量

85 阅读4分钟

0x01 了解变量

Rust语言的变量是一种绑定语义,相当于是把一个变量名和一个值绑定在一起,从而建立起了关联关系,类似于键值对。为了安全性的考虑,Rust的变量默认是不可以改变的,当然Rust也提供了另一种变量——可变变量。

0x02 命名规范

Rust变量名可以由字母,数字或者下划线组成。同时还有以下3个限制条件

  • 不能以数字开头
  • 字母区分大小写
  • 不能只有下划线

0x03 变量绑定

在其它语言中,我们用 var a = "hello world" 的方式给 a 赋值,也就是把等式右边的 "hello world" 字符串赋值给变量 a ,而在 Rust 中,我们这样写: let a = "hello world" ,同时给这个过程起了另一个名字:变量绑定

//不可变变量
let a = 10;
//可变变量
let b = 10;
//使用下划线开头忽略未使用的变量
let _c = 20;

0x04 变量解构

let 表达式不仅仅用于变量的绑定,还能进行复杂变量的解构:从一个相对复杂的变量中,匹配出该变量的一部分内容:

let (a, mut b): (bool,bool) = (true, false);

0x04 变量和常量之间的差异

  • 常量不允许使用 mut常量不仅仅默认不可变,而且自始至终不可变,因为常量在编译完成后,已经确定它的值。
  • 常量使用 const 关键字而不是 let 关键字来声明,并且值的类型必须标注。
  • 静态常量使用static关键字。

静态变量和常量很相似,但是在一个程序中,静态变量拥有精确固定的内存地址,对于静态变量的所有引用都指向相同的内存地址。静态变量也存在生命周期,但是其生命周期在程序中是最长的。静态变量不会在程序结束时调用drop函数。
静态变量是可以用mut来修饰的,一旦静态变量可变,就会出现多线程同时访问的场景,从而引发内存不安全的问题,因此对于static mut声明的变量必须在unsafe块中进行定义(有关unsafe的内容将在后续章节介绍)。

0x05 变量遮蔽 (Shadowing)

Rust 允许声明相同的变量名,在后面声明的变量会遮蔽掉前面声明的,如下所示:

fn main() {
    let x = 5;
    // 在main函数的作用域内对之前的x进行遮蔽
    let x = x + 1;

    {
        // 在当前的花括号作用域内,对之前的x进行遮蔽
        let x = x * 2;
        println!("The value of x in the inner scope is: {}", x);
    }

    println!("The value of x is: {}", x);
}

这个程序首先将数值 5 绑定到 x,然后通过重复使用 let x = 来遮蔽之前的 x,并取原来的值加上 1,所以 x 的值变成了 6。第三个 let 语句同样遮蔽前面的 x,取之前的值并乘上 2,得到的 x 最终值为 12。当运行此程序,将输出以下内容:

$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
   ...
The value of x in the inner scope is: 12
The value of x is: 6
fn main() {

//练习1

//error write

//Rust的变量默认情况下是不可变的。

// let x = 5;

// println!("The value of x is {}", x);

// // x = 6;

// println!("The value of x is {}", x);

// println!("Hello, world!");

  


//练习2

//在变量前加一个mut,则此变量为可变变量

// let mut x = 5;

// println!("The value of x is : {}",x);

// x = 6;

// println!("The value of x is : {}",x);

  


//练习3

//创建一个变量但是不使用,Rust会给一个警告

//以下划线作为变量的开头,Rust则不会给一个警告

// let _x = 5;

// let y = 10;

  


//练习4

//let表达式可以进行复杂变量的解构,从一个相对复杂的变量中

//匹配出该变量的一部分内容

// let (a,mut b) : (bool,bool) = (true,false);

// println!("a = {:?},b = {:?}",a,b);

// b = true;

// assert_eq!(a,b);

  


//练习5

//赋值语句中使用元祖,切片,结构体

// let (a,b,c,d,e);

// (a,b) = (1,2);

// // _ 代表匹配一个值,但是不关系具体的值是什么,因此没有使用

// //一个变量名而是使用了 _

// [c,..,d,_] = [1,2,3,4,5];

// Struct{e,..} = Struct{e:5};

// assert_eq!([1,2,1,4,5],[a,b,c,d,e]);

  


//练习6

/*

常量不允许用mut。常量不仅仅默认不可变,而且自始至终不可变,因为常量

编译完成后,已经确定它的值

常量使用const关键字而不是let关键字来申明

*/

// const MAX_POINTS:u32 = 100;

  


//练习7

//变量遮蔽

//Rust允许申明相同的变量名,后面申明的变量会遮蔽掉前面的申明

  


let x = 5;

//对let x = 5;变量申明进行遮蔽

let x = x + 1;

println!("The value of x is : {}",x);

{

//在当前作用域内{},对之前的x进行遮蔽

let x = x + 2;

println!("The value of x is : {}",x);

}

println!("The value of x is : {}",x);

//字符串类型

let spaces = " ";

println!("The value of spaces is : {}",spaces);

//usize数值类型

let spaces = spaces.len();

println!("The value of spaces is : {}",spaces);

  
  


}

// struct Struct{

// e:i32

// }

源码地址