Rust圣经笔记 2.变量

147 阅读5分钟

关键字列表

变量名解释变量名解释变量名解释
as强制类型转换,或useextern crate包和模块引入语句中的重命名extern链接一个外部包,或者一个宏变量(该变量定义在另外一个包中)loop无条件循环
break立刻退出循环false布尔值 falsematch模式匹配
const定义常量或原生常量指针fn定义一个函数或 函数指针类型 (function pointer type)mod定义一个模块
continue继续进入下一次循环迭代for遍历一个迭代器或实现一个 trait 或者指定一个更高级的生命周期move使闭包获取其所捕获项的所有权
crate链接外部包if基于条件表达式的结果来执行相应的分支mut在引用、裸指针或模式绑定中使用,表明变量是可变的
dyn动态分发特征对象impl为结构体或者特征实现具体功能pub表示结构体字段、impl 块或模块的公共可见性
else作为 ifif let 控制流结构的 fallbackinfor 循环语法的一部分ref通过引用绑定
enum定义一个枚举类型let绑定一个变量return从函数中返回
Self实现特征类型的类型别名self表示方法本身或当前模块static表示全局变量或在整个程序执行期间保持其生命周期
struct定义一个结构体super表示当前模块的父模块trait定义一个特征
true布尔值 truetype定义一个类型别名或关联类型unsafe表示不安全的代码、函数、特征或实现
use在当前代码范围内(模块或者花括号对)引入外部的包、模块等where表示一个约束类型的从句while基于一个表达式的结果判断是否继续循环

保留字列表

变量名解释变量名解释变量名解释
abstractasyncawait
becomeboxdo
finalmacrooverride
privtrytypeof
unsizedvirtualyield

变量绑定

在rust中如何表达将一个值给于一个变量这个动作呢,在诸如Java及其他语言中我们通常将这个动作称为赋值。 Rust中为什么不呢? 这需要结合Rust中很重要的一个特性所有权,我们或许能够理解一二。那么所有权又是啥。简单理解在Rust中每个值都将被一个变量所拥有,没有变量需要的值将被无情的抛弃。所有在这里使用使用赋值或许就没有这么恰当,赋值的表述是将一个值存放在一个变量中的一个中,而所有权是让变量拥有一条牵着值的链子(指针地址!指针地址!),使用绑定这个组词显得更加恰当。

变量可变性

将值分为不可变变量和可变变量,或许显得很麻烦,但我却并不这么认为,使用这种特性,我可以不用去猜测这个变量在什么地方做过改变。导致而是一眼丁真。 在大部分语言中变量介是默认可变的状态,可变就是变量在第一次赋值后可以通过再次赋值修改变量中的值如下

int a = 6;
a = 5;

在Java中这段代码是可以正常运行的,而在Rust中确是不一样的光景

let a = 6;
a = 5;
D:\rustProject\hello-world> cargo run hello-world
error[E0384]: cannot assign twice to immutable variable `a`
 --> src\main.rs:3:5
  |
2 |     let  a  = 6;
  |          -
  |          |
  |          first assignment to `a`
  |          help: consider making this binding mutable: `mut a`
3 |     a = 5;
  |     ^^^^^ cannot assign twice to immutable variable

For more information about this error, try `rustc --explain E0384`.
warning: `hello-world` (bin "hello-world") generated 2 warnings
error: could not compile `hello-world` (bin "hello-world") due to 1 previous error; 2 warnings emitted

这里编译器告诉我们cannot assign twice to immutable variable a说明Rust在默认的情况下变量是不能改变的。

如何改变这一结果呢 mut 关键字可以解决这个问题

let mut a  = 5;
a = 6;

如果上方代码这么编写,你大概率会得到一个警告

warning: value assigned to `a` is never read
 --> src\main.rs:2:13
  |
2 |     let mut a  = 5;
  |             ^
  |
  = help: maybe it is overwritten before being read?
  = note: `#[warn(unused_assignments)]` on by default

使用下划线_ 即可解决,当然从优化的角度来说这样的变量真的没有必要存在

变量解构

从相对复杂的变量中,匹配出变量的一部分内容

fn main() { 
	let (a, mut b): (bool,bool) = (true, false); 
	// a = true,不可变; b = false,可变 
	println!("a = {:?}, b = {:?}", a, b); 
	b = true; 
	assert_eq!(a, b); 
}

解构的花活

	let (mut a, b,c,d);

    // 元组 分别将1,2 绑定给a,b

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

    println!("{},{}",a,b);

    // 切片 取切片下标,注意 这里变量数量需要小于或等于切片长度,如果小于的话需要使用.. 或者 _ 进行替代

    // 如果..发生在两个变量之间,那么会省略当前变量到下一个可用变量之前的所有值。

    // 使用_进行变量替换时,需要遵守第一条中小于或等于切片长度,如果变量与_的和等于切片长度时..将失效

    [a,d,..,c,_] = [1,2,3,4,5];
	// 最后一行语句可以省略 返回关键字`return`及分号
    print!("{}{}{}",a,d,c)

需要注意的是,使用 += 的赋值语句还不支持解构式赋值。

变量和常量之间的差异

变量的值不能更改可能让你想起其他另一个很多语言都有的编程概念:常量(constant)。与不可变变量一样,常量也是绑定到一个常量名且不允许更改的值,但是常量和变量之间存在一些差异:

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

变量遮蔽

在Rust中允许声明同名变量,在同一作用域中后面的变量将遮蔽掉前面的变量

let a = "123";
let a = 123;