Skip to content
📖 Auto 版 Rust Book本书目录

常用集合 ​

Auto 的标准库包含许多非常有用的数据结构,称为 集合(collections)。大多数其他数据类型表示一个特定的值,而集合可以包含多个值。与内置的数组和元组类型不同,这些集合指向的数据存储在堆上,这意味着数据量不需要在编译时确定,可以在程序运行时增长或缩小。

在本章中,我们将讨论三种在程序中非常常用的集合:

  • 列表(List<T>)允许你将可变数量的值依次存储在一起。
  • 字符串(String)是字符的集合。我们之前已经提到过 String 类型,本章将深入讨论。
  • 哈希映射(Map<K, V>)允许你将一个值与特定的键关联起来。

我们将讨论如何创建和更新列表、字符串和哈希映射,以及每种集合的独特之处。

使用 List<T> 存储值列表 ​

我们首先介绍的集合类型是 List<T>,也称为列表(等价于 Rust 的 Vec<T>)。列表允许你在单个数据结构中存储多个值,这些值在内存中相邻排列。列表只能存储相同类型的值。

创建新列表 ​

要创建一个新的空列表,我们调用 List.new():

创建新列表并使用 `push` 添加元素

注意我们使用 var 使列表可变,以便使用 push 添加元素。元素类型从第一次 push 调用中推断 — 由于我们 push 了 10(一个 int),列表就是 List<int>。

读取列表元素 ​

有两种方式引用列表中存储的值:通过索引,或使用 ??(空值合并)运算符进行安全访问。

使用索引和 `??` 运算符读取列表元素

在 Auto 中,list[i] 返回 ?T(Option 类型)— 如果索引有效则为 Some(value),如果越界则为 None。?? 运算符提供默认值,替代了 Rust 中冗长的 .get(i).copied().unwrap_or(default) 模式。

这是 Auto 相对于 Rust 的一个关键安全改进:Auto 的列表索引永远不会 panic。你必须显式处理索引可能越界的情况。

遍历列表 ​

要访问列表中的每个元素,我们遍历所有元素:

使用 `for` 循环遍历列表

使用枚举存储多种类型 ​

列表只能存储相同类型的值。当你需要存储不同类型时,可以定义一个枚举,其变体持有不同的值类型:

定义枚举以在列表中存储不同类型的值

使用字符串存储 UTF-8 编码的文本 ​

我们在前面的章节中已经大量使用了 String。String 是一个可增长的、可变的、拥有的、UTF-8 编码的字符串类型。让我们看看一些常见操作。

创建和更新字符串 ​

创建和更新字符串

关键区别:

特性AutoRust
从字面量创建"hello".to_string()"hello".to_string()
从字面量创建String.from("world")String::from("world")
追加字符串s.push_str("bar")s.push_str("bar")

使用 f-字符串拼接 ​

Auto 使用 f-字符串插值进行字符串拼接,而非 Rust 的 + 运算符或 format! 宏:

使用 f-字符串拼接字符串

f-字符串是 Auto 构建字符串的首选方式。它们比 + 拼接更易读,且不获取任何变量的所有权。

字符串索引 ​

与 Rust 一样,Auto 不支持直接对字符串进行字节索引(例如 "hello"[0])。这是因为字符串是 UTF-8 编码的,字节索引可能不对应有效的字符边界。

要遍历字符,使用 chars 方法:

auto
for c in "hello".chars() {
    print(c.to_string())
}

使用哈希映射存储键值对 ​

我们最后介绍的常用集合是哈希映射。Map<K, V> 类型存储从类型 K 的键到类型 V 的值的映射。在 Auto 中,Map 通过 use.rust 指令从 Rust 标准库引入。

创建新哈希映射 ​

创建新哈希映射并插入键值对

关键区别:

特性AutoRust
导入use.rust std::collections::HashMapuse std::collections::HashMap;
创建空映射HashMap.new()HashMap::new()
插入map.insert(key, val)map.insert(key, val)

访问值 ​

要从哈希映射中获取值,使用 get 方法,它返回 ?V:

auto
use.rust std::collections::HashMap

fn main() {
    var scores = HashMap.new()
    scores.insert("Blue", 10)
    let score = scores.get("Blue") ?? 0
    print(f"Score: ${score}")
}

更新哈希映射 ​

使用相同键再次调用 insert 即可覆盖值:

auto
scores.insert("Blue", 25)  // 覆盖之前的值 10

总结 ​

Auto 的集合类型提供了与 Rust 相同的功能,但 API 更加简洁安全:

概念AutoRust
动态数组List<T>Vec<T>
创建列表List.new()Vec::new() / vec![]
添加元素v.push(val)v.push(val)
安全访问v[i] ?? defaultv.get(i).copied().unwrap_or(default)
遍历for item in vfor item in v
哈希映射Map<K, V> / HashMapHashMap<K, V>
字符串拼接f"${a}, ${b}"format!("{}, {}", a, b)
字符串追加s.push_str("text")s.push_str("text")

最显著的改进是 Auto 的安全列表索引 — v[i] 返回 ?T 而非 panic,?? 运算符提供了简洁的缺失值处理方式。这消除了一整类运行时错误。

在下一章中,我们将更深入地讨论错误处理。

基于 MIT 许可发布。