本文的参考代码在这里
枚举 enum
基本概念
枚举为您提供了一种表示某个值是一组可能的值之一的方法。
- 下面的代码定义了枚举
enum
类型,IpAddrKind
v4和v6
- 绑定枚举值时,须用
::
绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #[derive(Debug)] enum IpAddrKind { v4, v6 }
fn main() { let four = IpAddrKind::v4; let six = IpAddrKind::v6;
route(four); route(six); }
fn route(ip_kind: IpAddrKind) { println!("ip_kind -> {:?}", ip_kind); }
|
我们创建一个上一节提到的 struct
结构体,对ip的实际地址用字符串进行存储:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #[derive(Debug)] enum IpAddrKind { v4, v6 }
#[derive(Debug)] struct IpAddr { kind: IpAddrKind, address: String }
fn main() { let home = IpAddr { kind: IpAddrKind::v4, address: String::from("127.0.0.1"), };
let loopback = IpAddr { kind: IpAddrKind::v6, address: String::from("::1"), };
route(home); route(loopback); }
fn route(ip_kind: IpAddr) { println!("ip_kind -> {:?}", ip_kind); }
|
enum
可独自定义每个成员的数据类型
但上面的代码可以让 enum
直接存储类型为 String
, 省去更多代码,可以改写如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| #[derive(Debug)] enum IpAddrKind { v4(String), v6(String) }
fn main() { let home = IpAddrKind::v4(String::from("127.0.0.1")); let loopback = IpAddrKind::v6(String::from("::1"));
println!("home {:?}", home); println!("loopback {:?}", loopback); }
|
甚至可以再细化, 做到结构体无法完成的任务,例如ipv4一般是4个8 bit的 数值,定义类型时可和ipv6区分开来:
1 2 3 4 5 6 7 8 9 10 11 12 13
| #[derive(Debug)] enum IpAddrKind { v4(u8, u8, u8, u8), v6(String) }
fn main() { let home = IpAddrKind::v4(String::from(127, 0, 0, 1)); let loopback = IpAddrKind::v6(String::from("::1"));
println!("home {:?}", home); println!("loopback {:?}", loopback); }
|
其实我们在标准库里,可以看到一个专门定义ip的结构体,可以用来这样表达enum
:
1 2 3 4 5 6 7 8 9 10 11 12
| struct Ipv4Addr { }
struct Ipv6Addr { }
enum IpAddr { V4(Ipv4Addr), V6(Ipv6Addr), }
|
rust
里没有 null
值概念,null
的问题在于,如果您尝试将空值用作非空值,则会收到某种错误。所以用 None
代替,即无值。他在标准库的定义如下:
1 2 3 4
| enum Option<T> { None, Some(T), }
|