一起学Rust-枚举

一、枚举定义及使用

枚举的定义在其他许多的语言中都有实现,举例来说,比如C中的枚举,枚举值在未赋值的情况下默认从0开始递增或从上一个枚举值开始递增,值类型可以是整数或字符类型,实质只能保存整型:

enum {
    A = 'd',  //d 的 ascii码值
    B,        //e 的 ascii码值
    C,        //f 的 ascii码值
    D = 10,
    E,        //11
};

Rust中的枚举与C中的枚举不同,功能非常强大,可以用枚举表达更多的可能性数据。

看一下基本的枚举定义:

//定了一个性别的枚举
enum Gender {
    Male,
    Female,
}

这里面不同的是,Male和Female不是变量,而是枚举值,而不像是C中会访问到相应的数字。

#[derive(Debug)]
enum Gender {
    Male,
    Female,
}

println!("{:?}, {:?}", Gender::Male, Gender::Female);

----- 输出 -----
Male, Female

虽然输出看上去是字符串类型,但实际是枚举Gender类型

//这样是编译不通过的
if Gender::Male == "Male" {...}

枚举值的代数形式是可以与实际的值进行结合的,而且是可以结合不同类型的数据,这使得枚举的能力更强:

enum ErrorLevel {
    Error(String),
    Info(String, i32),
    Warning(String),
}

每一个枚举值可可以放入不同类型的数据,作为枚举的一部分,那么通过下面的例子看一下如何定义带数据的枚举值:

let info = ErrorLevel::Info("info error".to_string(), 3);

match info {
    ErrorLevel::Info(k, v)  => {
        println!("{}, {}", k, v);
    },
    _ => ()
}

上面的例子里面通过模式匹配获取了Info枚举值内的数据,这里需要注意的是上面的例子在match代码块后方就不能再使用info的变量了,这里涉及到Rust中所有权的特性,也是Rust中非常重要的特性,这里暂不过多的探讨。

不过上面的例子仅支持固定类型的值,对于不同级别的错误日志来说,有些时候会需要记录一些不同类型的数据,所以可能需要不同的参数类型(这样说稍微牵强),看下面枚举结合 泛型 的例子:

enum ErrorLevel<T> {
    Error(T),
    Info(T),
    Warning(T),
}
let info = ErrorLevel::Info("abc");  //可以通过自动推断类型
let info = ErrorLevel::<&str>::Info("abc");  //可以指定类型并赋值

三、内置常用枚举

Option<T> 枚举类型,通过IDE可以查看它的完整定义:

#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Option<T> {
    /// No value
    #[stable(feature = "rust1", since = "1.0.0")]
    None,
    /// Some value `T`
    #[stable(feature = "rust1", since = "1.0.0")]
    Some(#[stable(feature = "rust1", since = "1.0.0")] T),
}

简化如下

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

Option<T> 是一个非常重要的枚举类型,在程序中无需引用库,直接可以使用Some(T)和None。另外一个原因是因为Rust中去除了空类型,也就是没有null、nil、none、这种在其他语言中非常常见的空类型,而是使用 Option<T> 作为存在值和空值间的选择,因为 Option<T> 可以被赋予指定类型,即使当变量还为初始化时,也是明确变量应该被设置的类型。

let num:Option<i32> = None;  //当变量暂不可知时,赋予None

上面的例子中,赋值为None时必须明确Option的类型,通过None是无法推断Option中值的类型的。

在上一期的《一起学Rust-实战leetcode(一)》中使用到的HashMap,其get方法获取到的就是一个Option<T>枚举类型,存在则返回Some包含的值,哈希中不存在则返回None。

Result<T,E> 枚举类型,仅有两个枚举值:

enum Result<T, E> {
    Ok(T),    //成功情况
    Err(E)    //失败情况
}

在这个枚举用的比较广泛,例如 Tcp连接的创建、文件读取、标准输入等,会存在成功或异常的情况,所以通过枚举类型携带成功或错误的信息返回。

fn main() {
    let mut input  = String::new();

//    if let Ok(string_bytes) = stdin().read_line(&mut input) {
//        println!("{}, {}", string_bytes, input);
//    } else {
//        println!("error");
//    }

    //这里写法上方的写法意义是一样的,
    let res = stdin().read_line(&mut input);
    match res {
        Ok(v) => println!("{}, {}", v,  input),
        Err(e) => println!("{}", e)
    }
}

枚举类型就介绍到这里,要想快速掌握还是应该多多练习~

本文分享自微信公众号 - 可回收BUG(way-of-full-stack)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SIGAI学习与实践平台

Aster:具有柔性矫正功能的注意力机制场景文本识别方法

DeepAction八期飞跃计划还剩12个名额,联系小编,获取你的专属算法工程师学习计划(联系小编SIGAI_NO1)

49010
来自专栏AI科技大本营的专栏

阿里、京东、快手、华为......他们是如何构建一个个推荐系统“帝国”的?

推荐系统在人们的日常生活中随处可见,成为我们生命中不可或缺的一部分。作为当今应用最为广泛和成熟的 AI 技术之一,它是信息生产者、传播者与用户之间的桥梁,可以让...

22020
来自专栏全栈者

重温基础:ES9系列

所有整理的文章都收录到我《Cute-JavaScript》系列文章中,访问地址:http://js.pingan8787.com

10610
来自专栏全栈者

ssh免密登录原理与实现

作为开发者,所开发的每一个应用在成型后都需要部署,虽然我们使用着各式各样的部署工具,但是其背后最本质的东西完全一样,便是如何与服务器交互,而交互的第一步便涉及到...

29410
来自专栏DotNet Core圈圈

【译】尝试使用Nullable Reference Types

随着.NET Core 3.0 Preview 7的发布,C#8.0已被认为是“功能完整”的。这意味着它们的最大亮点Nullable Reference Typ...

9110
来自专栏全栈者

前端进阶之 a 可以同时 == 1 && == 2 && == 3吗?

当然,我们可以通过重写 Symbol.toPrimitive来制定转换规则,此方法在转原始类型时调用优先级最高。

9020
来自专栏AI科技大本营的专栏

200行代码解读TDEngine背后的定时器

其主要源码地址如下:https://github.com/taosdata/TDengine/blob/master/src/util/src/ttimer.c

14620
来自专栏计算机视觉战队

基础干货——线性分类(上)

图像分类的任务,就是从已有的固定分类标签集合中选择一个并分配给一张图像。我们还介绍了k-Nearest Neighbor (k-NN)分类器,该分类器的基本思想...

13110
来自专栏全栈者

制定自己团队的前端开发规范

后续的文章我也补充齐全了,一共有两篇,都是实战篇,一篇是制定自己团队的前端开发规范之 eslint,另外一篇是手摸手带你实践标准的前端开发规范,希望大家可以去看...

10310
来自专栏全栈者

看看你知道的“浅拷贝”是对的吗

关于本篇文章的起源是一位大佬在面试的时候,询问应聘者关于浅拷贝的知识后,在应聘者的回答中,笔者发现有好一部分人对浅拷贝都是错误的,故有了此篇内容。

7220

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励