方唐镜

大人,我这里有三千个证人(Vector),还有一本绝密账本(HashMap),上面记着每个官员收了多少...哦不,是做了多少好事!

包龙星

这么多? 之前的数组(Array)长度固定,装不下啊!

看来得用点能屈能伸的神器了!

雷豹

笨!用 Vector!它在堆上,想装多少装多少!再用 HashMap 查账,一查一个准!

第二十三回:人海战术与查账秘籍

Rust 标准库提供了强大的集合(Collections),专门用来对付“方唐镜”这种带一堆人来闹事的。

📦 动态数组 (Vector) —— 衙门的大牢

普通数组(Array)就像以前的衙门,只有几间房(固定长度)。Vec<T> 则是现代化大牢,想关多少人就关多少人(可变长度)。

fn main() {
    // 新建一个空的大牢
    let mut jail: Vec<&str> = Vec::new();
    
    // 把犯人关进去
    jail.push("常威");
    jail.push("来福");
    jail.push("打更的");

    // 也可以直接用宏一锅端
    let witnesses = vec!["卖菜的", "这边的女士", "那边的朋友"];
    
    // 提审犯人(访问元素)
    // 注意:要小心越界,不然程序会 panic(衙门塌了)
    match jail.get(100) {
        Some(criminal) => println!("提审:{}", criminal),
        None => println!("大人,牢里没这么多人啊!"),
    }
}

🧵 字符串 (String) —— 吵架的艺术

在 Rust 里,String 是可变的,就像你的口供,想改就改(当然得有所有权)。

注意: Rust 的字符串是 UTF-8 编码的。这意味你可以用中文骂人,甚至用 Emoji 骂人!

fn main() {
    let mut confession = String::from("我看见常威");
    
    // 追加口供
    confession.push_str(" 在打来福"); 
    confession.push('!');
    
    println!("口供:{}", confession); // 我看见常威 在打来福!
    
    // 字符串拼接
    let s1 = String::from("贪官");
    let s2 = String::from("污吏");
    // s1 被移动到了 s3,s1 不能再用了!
    let s3 = s1 + &s2; 
    println!("结果:{}", s3);
}

🗺️ 哈希表 (HashMap) —— 阎王的生死簿

HashMap<K, V> 专门用来记账。给我一个名字(Key),我告诉你他该判几年(Value)。

use std::collections::HashMap;

fn main() {
    let mut crimes = HashMap::new();
    
    // 记上一笔
    crimes.insert(String::from("常威"), 999);
    crimes.insert(String::from("来福"), 0);

    // 查账
    let name = String::from("常威");
    // get 返回 Option<&V>
    if let Some(years) = crimes.get(&name) {
        println!("{} 判刑:{} 年", name, years);
    }

    // 还可以如果没有记录,就记上一笔
    // 如果“方唐镜”没有记录,就记上 50 年
    crimes.entry(String::from("方唐镜")).or_insert(50);
}

动手时刻:统计罪名

方唐镜一直在说“荒唐”。请你写一段代码,统计下面这段话里,“荒唐”出现了几次。

"荒唐!真是荒唐!这简直是荒唐之极!"

查看参考答案
use std::collections::HashMap;

fn main() {
    let text = "荒唐 真是 荒唐 这 简直 是 荒唐 之极";
    let mut map = HashMap::new();

    for word in text.split_whitespace() {
        // 统计词频的神奇咒语
        let count = map.entry(word).or_insert(0);
        *count += 1;
    }

    println!("荒唐出现了 {} 次", map.get("荒唐").unwrap_or(&0));
}
下一回:面向对象(祖传秘方) →