返回介绍

7.1 枚举

发布于 2024-10-13 11:25:29 字数 2406 浏览 0 评论 0 收藏 0

像 C 那样,从 0 开始自增,或显式设置值。

成员类型是能容纳成员值的最小整数。

enum Letter {
  A,
  B,
  C = 10,
  D,
}

assert_eq!(Letter::A as i32, 0);
assert_eq!(Letter::B as i32, 1);
assert_eq!(Letter::D as i32, 11);

成员可以额外关联(associated)数据。

  • 单值: (T)
  • 元组: (T1, T2 ...)
  • 结构: {name:T, ...)
#[derive(Debug)]
enum Letter {
  A,
  B(i32),
  C(i32, String),
  D{x: i32, y: i32},
}

fn main() {
  let d = Letter::D{x: 1, y: 2};
  println!("{:?}", d);
}

变量 d 内存布局: [variant_value, x, y] ,也就是 [3, 1, 2] 。长度 32 ,因为 Letter::C 布局 [value, i32, ptr, len, cap] ,按 8 字节对齐。从这点看,其内存分配和使用方式类似联合(union)。

携带关联值的枚举可以实现 多态 效果。例如: enum JSON { Null, Boolean(bool), Number(i64) ... } ,统一以 JSON 出现,但每个具体成员都有自定义行为,类似子类扩展。

use 缩写。

fn main() {
  use Letter::*;

  let d = D{x: 1, y: 2};
  println!("{:?}", d);
}

matchif-let 解构关联数据。

enum Lettle {
  A(i32, i32),
  B{x: i32, y: i32},
}

fn main() {
  let b = Lettle::B{ x: 11, y: 22 };

  match b {
    Lettle::A(x, y) => println!("{} {}", x, y),
    Lettle::B{x, y} => println!("{} {}", x, y),
  }

  if let Lettle::B{x, y} = b {
    println!("{} {}", x, y);
  }
}

Option<T>

两个成员,要么有效值,要么空值。

enum Option<T> {
  Some(T),
  None,
}

之所以不使用 Null ,是因为它在某些场合(如数据库)代表一个正常值。

可用作函数可选参数(默认值),结构体可选字段等。

fn main() {
  let x = Some(123);

  if let Some(v) = x {
    println!("{}", v);
  }

  match x {
    Some(v) => println!("{}", v),
    None  => println!("None"),
  }
}

返回 Option<T> 的函数,也可用 ? 操作符向外传播 None 值。

fn test() -> Option<i32> {
  None
}

fn call() -> Option<i32> {
  let x: i32 = test()?;
  Some(x + 100)

  // let x: i32 = match test() {
  //   Some(v) => v,
  //   None  => return None,     
  // }
}

fn main() {
  assert_eq!(call(), None);
}

Result<T, E>

Option 可选值不同, Result 用于函数返回值,表示可恢复性错误处理。

enum Result<T, E> {
  Ok(T),
  Err(E),
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文