【Fitz】Rust 变量 variable

说明:本文主要是Rust语言圣经相关章节的学习笔记,大部分与其内容相同,欢迎阅读原文。

变量

在大多数编程语言中,要么只支持声明可变的变量(灵活性),要么只支持声明不可变的变量(安全性),而 Rust 两者都要。这样做的一个优点就是运行性能上的提升,因为将无需改变的变量声明为不可变可以避免一些多余的 runtime 检查。

Rust对于变量的命名,需要遵循Rust命名规范

Rust 的变量默认是不可变的,使用 mut 关键字可以将变量变为可变的。这种规则可以使代码更加清晰,只有需要变量可变时才会对应地声明,并且提示开发者“这个变量在后面会发生改变”。选择变量可变还是不可变,取决于使用场景。不可变可能会丧失灵活性和性能(涉及内存的分配),可变则可能会降低代码的可读性。

类似于 let s = "hello world" 的样式,可以用来绑定变量,即将一个对象绑定给一个变量,也是将对象的所有权赋给该变量。

变量解构

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

let (a, mut b): (bool, bool) = (true, false);
b = true;
println!("a = {:?}, b = {:?}");

解构式赋值

在 Rust 1.59 版本后,可以在赋值语句的左式中使用元组、切片和结构体模式了。示例代码如下:

struct Struct {
    e: i32
}

fn main() {
    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]);
}

这种使用方式跟之前的 let 保持了一致性,但是 let 会重新绑定,而这里是对之前绑定的变量进行再赋值。需要注意:使用 += 的赋值语句还不支持解构式赋值。这里涉及到了一些模式匹配的语法,这是一种函数式编程方法,可以到模式匹配中深入了解。

变量与常量之间的差异

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

Rust 常量的命名约定是全部字母都使用大写,并使用下划线分隔单词,对于数字字面量可以插入下划线提高可读性,如:

const SMALL_TARGET: u32 = 100_000_000;

常量可以在任意作用域内声明,包括全局作用域,在声明的作用域内,常量在程序运行的整个过程中都有效。这对于需要在多处代码共享一个不可变的值时非常有用。

在 Rust 中,任何一个可用来包含代码的大括号都是一个单独的作用域(但类似于 Struct {} 这样用来定义数据类型的大括号,不在讨论范围内),作用域相关的具体内容可以到理解Rust的变量作用域深入了解。

实际使用中,最好将程序中用到的硬编码值都声明为常量,对于代码后续的维护有莫大的帮助。如果将来需要更改硬编码的值,也只需要在代码中更改一处即可。

变量遮蔽(shadowing)

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

let a = 1;
let a = 2;  //对之前的x进行遮蔽

变量遮蔽是使用 let 声明了完全不同的新变量,两个变量只是恰好拥有同样的名称。该操作涉及一次内存对象的再分配。而 mut 声明的变量可以修改同一个内存地址上的值,不会发生内存对象的再分配,性能更好。

变量遮蔽的用处在于,如果在某个作用域内无需再使用之前的变量,可以重复使用变量名字,如:

let spaces = "     ";
let spaces = spaces.len();
posted @ 2022-03-14 15:41  AlphaFitz  阅读(75)  评论(0编辑  收藏  举报