Rust 语言从入门到实战
唐刚
Rust 语言中文社区联合创始人
5266 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 36 讲
Rust 语言从入门到实战
15
15
1.0x
00:00/00:00
登录|注册

08|Option<T>与Result<T, E>、迭代器

你好,我是 Mike,今天我们一起来重点学习在 Rust 中高频使用的 Option<T>Result<T, E>、迭代器,通过学习这些内容,我们可以继续夯实集合中所有权相关的知识点。
Option<T>Result<T, E> 并不是 Rust 的独创设计,在 Rust 之前,OCaml、Haskell、Scala 等已经使用它们很久了。新兴的一批语言 Kotlin、Swift 等也和 Rust 一样引入了这两种类型。而 C++17 之后也引入了它们。
这其实能说明使用 Option<T>Result<T, E> 逐渐成了编程语言圈子的一种新共识。而迭代器已经是目前几乎所有主流语言的标配了,所以我们也来看看 Rust 中的迭代器有什么独到的地方。
如果你习惯了命令式编程或 OOP 编程,那么这节课我们提到各种操作对你来说可能有点陌生,不过也不用担心,这节课我设计了大量示例,你可以通过熟悉这些示例代码,掌握 Rust 中地道的编程风格。

Option<T>Result<T, E>

Option<T>Result<T, E> 在 Rust 代码中随处可见,但是我们到现在才开始正式介绍,就是因为它们实际是带类型参数的枚举类型。

Option<T> 的定义

pub enum Option<T> {
None,
Some(T),
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Rust中的 `Option<T>`、`Result<T, E>` 和迭代器是重要概念。`Option<T>` 用于处理空值,`Result<T, E>` 统一表达了函数的正确和错误情况。解包操作是常见的,但实际上很多时候并不需要手动解包。`Option<T>` 上的常用方法包括 `map()`、`cloned()`、`is_some()` 等,而 `Result<T, E>` 上的常用方法有 `map()`、`is_ok()`、`and_then()` 等。`Option<T>` 与 `Result<T, E>` 之间可以相互转换。迭代器可以按需使用,惰性计算,安全地访问边界。迭代器上有一个标准方法 `next()`,返回 `Option<Item>`。文章通过示例代码详细介绍了这些概念及其常用方法,帮助读者更好地理解Rust编程风格。文章还介绍了迭代器的三种类型,以及如何在Rust中获取集合元素的所有权。此外,文章还解释了for语句的背后原理,以及如何在for语句中获取集合元素的引用而不消耗集合所有权。整体而言,本文深入探讨了Rust中的 `Option<T>`、`Result<T, E>` 和迭代器的概念,以及它们在实际编程中的应用,为读者提供了深入的技术理解和实践指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Rust 语言从入门到实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(9)

  • 最新
  • 精选
  • 天高地迥
    Vec<String> []索引不能move的原因思考: Vec实现了Index trait的index方法,该方法返回一个引用。然后使用[]语法糖的时候,编译器会自动解引用:v[0]变成*v.index(&0)。其实错误的本质是borrowed value不能move out。

    作者回复: 👍

    2023-11-06归属地:上海
    13
  • Ransang
    HashMap实现了into_iter(),因此可以用for语句获取其所有权,另外我在老师发的hashmap的文档中发现HashMap的iter()和iter_mut()是分类在Implementations中,而into_iter()是在Trait Implementations中,请问这里面有什么特殊之处吗

    作者回复: 对,你发现了一个惊人的事实,有用的知识又增加了! 你会发现,所有的 iter() 和 iter_mut() 都是实现在 types 上的,它们的输出结果就是将 type 变成另一个type_i,这个type_i 实现了 Iterator trait。而对所有实现了 Iterator trait 的,又自动为其实现了 IntoIterator trait,into_iter() 正是这个trait中的方法。第09讲会讲到这方面的预备知识。 这种分离实现是Rust的典型特色,因为不是所有的类型都需要实现这3种迭代器的,这样设计可带来最大程度的灵活性。

    2023-11-15归属地:上海
    3
  • 小可爱(`へ´*)ノ
    老师讲的很好,多了解rust底层规则,才能写出更好的代码。

    作者回复: 谢谢

    2023-12-13归属地:四川
    2
  • 鸠摩智
    let arr = vec![1,3,3,4]; let a = arr[0]; println!("{}", a); println!("{:?}", arr); 对于Vec<u32>是可以用v[0]的,因为u32是可以Copy的

    作者回复: 是的

    2023-11-09归属地:江苏
    1
  • Marco
    老师你好。 "next() 方法"这一节的例子也可以改为如下结构吧 loop { match an_iter.next() { Some(i) => println!("{i}"), None => break, } }

    作者回复: 可以的。

    2023-11-07归属地:中国香港
    1
  • PEtFiSh
    for (k, v) in myhash { //`myhash` moved due to this implicit call to `.into_iter()` // todo: // 这里会获得v的所有权,并且消耗掉myhash } println!("{:?}", myhash); //value borrowed here after move

    作者回复: 👍👍

    2023-11-06归属地:上海
    1
  • wcf
    为什么会有这个差异呢?你可以从我们第 2 讲所有权相关知识中找到答案。 ============ 没看出来为什么?

    作者回复: 你运行一下就知道怎么回事了。简单的说是,u32与String在再赋值时的行为不同。

    2024-01-24归属地:北京
  • -
    定义了类型以后,let a: Vec<u32> = [1, 2, 3, 4, 5];语法错误 修改为let a= [1, 2, 3, 4, 5];

    作者回复: let a: Vec<u32> = vec![1, 2, 3, 4, 5];

    2023-11-06归属地:北京
  • superggn
    思考题: 用 entry use std::collections::hash_map::Entry; match some_hashmap.entry(key) { Entry::Occupied(value) => ... Entry::Vacant(vacant entry) => ... } 具体类型应该有点对不上, 回头看看文档的
    2023-12-14归属地:北京
收起评论
显示
设置
留言
9
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部