结构体和枚举

结构体

在实例化一个结构体时将它整体标记为可变的,但是 Rust 不允许我们将结构体的某个字段专门指定为可变的。一旦实例可变,那么实例中的所有字段都将是可变的。

  • 定义

struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}
  • 创建

  1. 初始化实例时,每个字段都需要进行初始化

  2. 初始化时的字段顺序不需要和结构体定义时的顺序一致

#![allow(unused)]
fn main() {
    let user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
}

当函数参数和结构体字段同名时,可以直接使用缩略的方式进行初始化,跟 TypeScript 中一模一样。

  • 更新语法

.. 语法表明凡是我们没有显示声明的字段,全部从 user1 中自动获取。需要注意的是 ..user1 必须在结构体的尾部使用。

值得注意的是:username 所有权被转移给了 user2,导致了 user1 无法再被使用,但是并不代表 user1 内部的其它字段不能被继续使用。

  • 元组结构体

  • 空struct

如果想在结构体中使用一个引用,就必须加上生命周期,否则就会报错。

  • #[derive(Debug)] 打印结构体

{:?},{:#?}

dbg!宏:拿走表达式的所有权,打印出相应的文件名、行号等 debug 信息,最终还会把表达式值的所有权返回

当解构一个变量时,可以同时使用 move 和引用模式绑定的方式。当这么做时,部分 move 就会发生:变量中一部分的所有权被转移给其它变量,而另一部分我们获取了它的引用。

在这种情况下,原变量将无法再被使用,但是它没有转移所有权的那一部分依然可以使用,也就是之前被引用的那部分。

枚举

任何类型的数据都可以放入枚举成员中: 例如字符串、数值、结构体甚至另一个枚举。

  • Quit 没有任何关联数据

  • Move 包含一个匿名结构体

  • Write 包含一个 String 字符串

  • ChangeColor 包含三个 i32

从代码规范角度来看,枚举的实现更简洁,代码内聚性更强,不像结构体的实现,分散在各个地方。

  • Option 枚举用于处理空值

Rust 吸取了众多教训,决定抛弃 null,而改为使用 Option 枚举变量来表述这种结果。

Option 枚举包含两个成员,一个成员表示含有值:Some(T), 另一个表示没有值:None

其中 T 是泛型参数,Some(T)表示该枚举成员的数据类型是 T,换句话说,Some 可以包含任何类型的数据。

只要一个值不是 Option<T> 类型,你就 可以 安全的认定它的值不为空。这是 Rust 的一个经过深思熟虑的设计决策,来限制空值的泛滥以增加 Rust 代码的安全性。

plus_one 通过 match 来处理不同 Option 的情况。

Last updated