首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
Rust简介
Rust 环境搭建
Cargo 教程
Rust 输出到命令行
Rust 基础语法
Rust 数据类型
Rust 注释
Rust 函数
Rust 条件语句
Rust 循环
Rust 所有权
Rust Slice(切片)类型
Rust 结构体
Rust 枚举类
Rust 组织管理
Rust错误处理
Rust 泛型与特性
Rust 生命周期
Rust 文件与 IO
Rust 集合与字符串
Rust 面向对象
Rust 并发编程
当前位置:
首页>>
技术小册>>
Rust入门教程
小册名称:Rust入门教程
枚举类在 Rust 中并不像其他编程语言中的概念那样简单,但依然可以十分简单的使用: 实例 ``` #[derive(Debug)] enum Book { Papery, Electronic } fn main() { let book = Book::Papery; println!("{:?}", book); } ``` 运行结果: ``` Papery ``` 书分为纸质书(Papery book)和电子书(Electronic book)。 如果你现在正在开发一个图书管理系统,你需要描述两种书的不同属性(纸质书有索书号,电子书只有 URL),你可以为枚举类成员添加元组属性描述: ``` enum Book { Papery(u32), Electronic(String), } let book = Book::Papery(1001); let ebook = Book::Electronic(String::from("url://...")); ``` 如果你想为属性命名,可以用结构体语法: ``` enum Book { Papery { index: u32 }, Electronic { url: String }, } let book = Book::Papery{index: 1001}; ``` 虽然可以如此命名,但请注意,并不能像访问结构体字段一样访问枚举类绑定的属性。访问的方法在 match 语法中。 ###match 语法 枚举的目的是对某一类事物的分类,分类的目的是为了对不同的情况进行描述。基于这个原理,往往枚举类最终都会被分支结构处理(许多语言中的 switch )。 switch 语法很经典,但在 Rust 中并不支持,很多语言摒弃 switch 的原因都是因为 switch 容易存在因忘记添加 break 而产生的串接运行问题,Java 和 C# 这类语言通过安全检查杜绝这种情况出现。 Rust 通过 match 语句来实现分支结构。先认识一下如何用 match 处理枚举类: 实例 ``` fn main() { enum Book { Papery {index: u32}, Electronic {url: String}, } let book = Book::Papery{index: 1001}; let ebook = Book::Electronic{url: String::from("url...")}; match book { Book::Papery { index } => { println!("Papery book {}", index); }, Book::Electronic { url } => { println!("E-book {}", url); } } } ``` 运行结果: ``` Papery book 1001 ``` match 块也可以当作函数表达式来对待,它也是可以有返回值的: ``` match 枚举类实例 { 分类1 => 返回值表达式, 分类2 => 返回值表达式, ... } ``` 但是所有返回值表达式的类型必须一样! 如果把枚举类附加属性定义成元组,在 match 块中需要临时指定一个名字: 实例 ``` enum Book { Papery(u32), Electronic {url: String}, } let book = Book::Papery(1001); match book { Book::Papery(i) => { println!("{}", i); }, Book::Electronic { url } => { println!("{}", url); } } ``` match 除了能够对枚举类进行分支选择以外,还可以对整数、浮点数、字符和字符串切片引用(&str)类型的数据进行分支选择。其中,浮点数类型被分支选择虽然合法,但不推荐这样使用,因为精度问题可能会导致分支错误。 对非枚举类进行分支选择时必须注意处理例外情况,即使在例外情况下没有任何要做的事 . 例外情况用下划线 _ 表示: 实例 ``` fn main() { let t = "abc"; match t { "abc" => println!("Yes"), _ => {}, } } ``` ###Option 枚举类 Option 是 Rust 标准库中的枚举类,这个类用于填补 Rust 不支持 null 引用的空白。 许多语言支持 null 的存在(C/C++、Java),这样很方便,但也制造了极大的问题,null 的发明者也承认这一点,"一个方便的想法造成累计 10 亿美元的损失"。 null 经常在开发者把一切都当作不是 null 的时候给予程序致命一击:毕竟只要出现一个这样的错误,程序的运行就要彻底终止。 为了解决这个问题,很多语言默认不允许 null,但在语言层面支持 null 的出现(常在类型前面用 ? 符号修饰)。 Java 默认支持 null,但可以通过 @NotNull 注解限制出现 null,这是一种应付的办法。 Rust 在语言层面彻底不允许空值 null 的存在,但无奈null 可以高效地解决少量的问题,所以 Rust 引入了 Option 枚举类: ``` enum Option<T> { Some(T), None, } ``` 如果你想定义一个可以为空值的类,你可以这样: ``` let opt = Option::Some("Hello"); ``` 如果你想针对 opt 执行某些操作,你必须先判断它是否是 Option::None: 实例 ``` fn main() { let opt = Option::Some("Hello"); match opt { Option::Some(something) => { println!("{}", something); }, Option::None => { println!("opt is nothing"); } } } ``` 运行结果: ``` Hello ``` 如果你的变量刚开始是空值,你体谅一下编译器,它怎么知道值不为空的时候变量是什么类型的呢? 所以初始值为空的 Option 必须明确类型: 实例 ``` fn main() { let opt: Option<&str> = Option::None; match opt { Option::Some(something) => { println!("{}", something); }, Option::None => { println!("opt is nothing"); } } } ``` 运行结果: ``` opt is nothing ``` 这种设计会让空值编程变得不容易,但这正是构建一个稳定高效的系统所需要的。由于 Option 是 Rust 编译器默认引入的,在使用时可以省略 Option:: 直接写 None 或者 Some()。 Option 是一种特殊的枚举类,它可以含值分支选择: 实例 ``` fn main() { let t = Some(64); match t { Some(64) => println!("Yes"), _ => println!("No"), } } ``` ###if let 语法 实例 ``` let i = 0; match i { 0 => println!("zero"), _ => {}, } ``` 放入主函数运行结果: ``` zero ``` 这段程序的目的是判断 i 是否是数字 0,如果是就打印 zero。 现在用 if let 语法缩短这段代码: ``` let i = 0; if let 0 = i { println!("zero"); } ``` if let 语法格式如下: ``` if let 匹配值 = 源变量 { 语句块 } ``` 可以在之后添加一个 else 块来处理例外情况。 if let 语法可以认为是只区分两种情况的 match 语句的"语法糖"(语法糖指的是某种语法的原理相同的便捷替代品)。 对于枚举类依然适用: 实例 ``` fn main() { enum Book { Papery(u32), Electronic(String) } let book = Book::Electronic(String::from("url")); if let Book::Papery(index) = book { println!("Papery {}", index); } else { println!("Not papery book"); } } ```
上一篇:
Rust 结构体
下一篇:
Rust 组织管理
该分类下的相关小册推荐:
暂无相关推荐.