番外 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"

🚀 总结:为什么这么写?

  1. 链式调用风格
    Rust 非常提倡链式调用,因为迭代器方法(mapcollect 等)既简洁又高效。

  2. 零拷贝操作
    通过 iter() 和解引用 |&word|,避免了额外的数据拷贝,提升了性能。

  3. 类型推断机制

    • collect() 会根据返回类型推断出是 Vec<String> 还是 String
    • 只有当推断不明确时才需要像 collect::<String>() 这样显式标注类型。
posted @ 2025-03-11 21:55  代码世界faq  阅读(94)  评论(0)    收藏  举报