番外 rust基础-链式调用
🌿 1. capitalize_words_vector 函数解析
fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
words.iter().map(|&word| capitalize_first(word)).collect()
}
//上述代码完整的闭包写法
fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
words.iter().map(|word: &&str| -> String {
// 这里我们用 *word 来解引用,将 &&str 变成 &str
let inner_word: &str = *word;
capitalize_first(inner_word)
}).collect::<Vec<String>>()
}
🔍 逐步拆解:
1️⃣ words.iter()
- 对切片进行迭代,
words是&[&str]类型,调用.iter()会得到迭代器,每一项是&&str(对&str的引用的引用)。
2️⃣ |&word| 解构
- |&word| 是 解构匹配,是将参数进行解构,进行匹配拿取对应结构,更灵活的拿到内部数据。
- 这也是闭包写法,相当于匿名函数
3️⃣ capitalize_first(word)
- 这一步调用你之前写好的函数,把每个字符串首字母大写,得到的是一个
String。
4️⃣ .collect() 收集结果到 Vec
- 迭代器最后的“终结”操作是
.collect(),可以把迭代器的结果收集成一个容器。 - 因为我们希望得到的是一个
Vec<String>,Rust 可以从函数签名自动推断出collect()的目标类型是Vec<String>,所以无需额外标注类型。
🪄 最终效果:
["hello", "world"] -> ["Hello", "World"]
🌿 2. capitalize_words_string 函数解析
fn capitalize_words_string(words: &[&str]) -> String {
words.iter().map(|&word| capitalize_first(word)).collect::<String>()
}
🔍 逐步拆解:
这个函数和上面的逻辑几乎一样,但最后的 .collect() 收集成一个字符串 而不是向量:
1️⃣ words.iter()
- 迭代切片,得到每个单词的引用(
&&str)。
2️⃣ |&word| 解引用
- 转换成
&str。
3️⃣ capitalize_first(word)
- 首字母大写,得到
String。
4️⃣ .collect::<String>()
- 和之前的
Vec<String>类似,但这次我们明确告诉 Rust 收集成一个字符串。 collect::<String>()会把所有String拼接在一起。- 为什么要标注
<String>?- 因为
.collect()是泛型方法,可能收集成不同容器。 - 对于拼接字符串这种情况,Rust 无法从签名自动推断目标类型,所以我们标注
<String>来告诉编译器。
- 因为
🪄 最终效果:
["hello", " ", "world"] -> "Hello World"
🚀 总结:为什么这么写?
-
链式调用风格
Rust 非常提倡链式调用,因为迭代器方法(map、collect等)既简洁又高效。 -
零拷贝操作
通过iter()和解引用|&word|,避免了额外的数据拷贝,提升了性能。 -
类型推断机制
collect()会根据返回类型推断出是Vec<String>还是String。- 只有当推断不明确时才需要像
collect::<String>()这样显式标注类型。

浙公网安备 33010602011771号