Rust之Enum枚举基础

1,046 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第25天,点击查看活动详情

基本概念

在强类型语言中,任何变量都必须属于一种类型。

比如说:

  • 整型
  • 布尔
  • 浮点型
  • 字符串
  • 字符
  • 字节
  • struct

等等。

我们存储一个年龄,就可以用整型。

存储一个姓名,就可以用字符串。

那么存性别呢?

你可以用整型:

  • 1 代表男
  • 2 代表女

当然,你当然可以用别的数字来代表你认为合理的别的性别,我是没意见的。

这样写,类型的观念不是很强,无法来约束有效值,比如说,你规定除了1和2之外都是无效性别,偏偏有人传了一个3给你,你咋办?

此时,Enum 登场,利用Enum来新建一个类型,这个类型可以取得值是可以被枚举的,也就是说有限的。

rust Enum 定义一个新类型

enum Gender {
    Man,
    Woman,
}

看上面的定义,我们为这个系统引进了一个新的类型Gender, 取值有两个Gender::Man, Gender::Woman

rust 创建枚举类型的变量

let a = Gender::Man;
let b = Gender::Woman;

rust的Enum可以关联变量

别的语言里,这个Enum可能就到此为止了,没有多余的东西了。

rust又在这种原本到此为止的地方加了东西。

先看下面这种定义:

enum Gender {
    Man(String), 
    Woman(String),
}

你可以发现,Man 和 Woman 后面又加了一个String。

使用的时候像这样:

let a = Gender::Man(String::from("小明"));
let b = Gender::Woman(String::from("小红"));

我们可以在Gender类型的变量中,添加额外的数据,这个数据可以是任意的。

例如,上例中 : a 就代表一个男性,并且叫小明
b 就代表一个女性,并且叫小红

每一个枚举值,可以关联的变量类型,还可以不同:

enum Gender {
    Man(String),
    Woman(u8),
}

let a = Gender::Man(String::from("小明"));
let b = Gender::Woman(22);

这个例子就是说:
我们如果是一个男性,那么就存储他的姓名
如果是一个女性,就存储她的年龄。

你可能会问,有这种需求吗?

当然,上面的例子是瞎整出来的,因为一开始用了性别来举例子。

下面这个例子是官方的,你可能会认同这种东西了:

    enum IpAddr {
        V4(u8, u8, u8, u8),
        V6(String),
    }

    let home = IpAddr::V4(127, 0, 0, 1);

    let loopback = IpAddr::V6(String::from("::1"));

这意思就是说,我想搞一个存储IP的东西,我们知道,IP地址格式现在只有两种,ipv4, ipv6。

ipv4的ip地址,是四个数字组成的例如:127.0.0.1。 ipv6的ip地址,是很长的一个字符串,当然也是数字,但是这里用字符串来表示。

不同的IpAddr用不同的类型去存储,这很好理解。

但是他们总的类型还是 IpAddr这个类型,函数传参啥的,就很方便。

我感觉这有点像 C语言里的Union的概念。。。只是有点像。

还可以给Enum加方法和关联函数

这玩意越来越像 struct 了。。

enum Gender {
    Man(String),
    Woman(u8),
}

impl Gender {
    fn show_info(&self){
        // ......
    }
}

如果不告诉你,Gender 是个枚举类型,你光看下面的impl代码,还真以为Gender是个struct。

如何将enum的关联数据取出来

可以用 match语句或者 if let 语句,这里就不提了,后面再说。