Chuyển đến nội dung chính

レッスン 6: クロージャ、イテレータ、コレクション

クロージャ、Fn/FnMut/FnOnce 特性。イテレーター特性、イテレーターアダプター (マップ、フィルター、フォールド)。 Vec、HashMap、HashSet、BTreeMap。カスタムイテレータの収集、連鎖。

💻 プログラミング — レッスン 6 レッスン 6: クロージャ、イテレータ、コレクション

Rust: 基本から上級まで

パート 2: 高度な Rust

xdev.asia

1. クロージャ

fn main() {
    // Closure syntax
    let add = |a: i32, b: i32| a + b;
    println!("{}", add(2, 3)); // 5

    // Capture environment
    let name = String::from("Rust");
    let greet = || println!("Hello, {}!", name);     // Fn — borrow
    greet();

    let mut count = 0;
    let mut increment = || { count += 1; };          // FnMut — mutable borrow
    increment();

    let name = String::from("Rust");
    let consume = move || println!("Consumed: {}", name); // FnOnce — move ownership
    consume();
    // println!("{}", name); // ❌ name đã bị move
}

// Closure as parameter
fn apply<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 {
    f(x)
}

// Return closure
fn make_adder(x: i32) -> impl Fn(i32) -> i32 {
    move |y| x + y
}

2. イテレータ

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    // Chaining adapters
    let result: Vec<i32> = numbers.iter()
        .filter(|&&x| x % 2 == 0)        // Lọc số chẵn
        .map(|&x| x * x)                  // Bình phương
        .collect();
    // [4, 16, 36, 64, 100]

    // fold — accumulate
    let sum: i32 = numbers.iter().fold(0, |acc, &x| acc + x);

    // find, any, all
    let first_even = numbers.iter().find(|&&x| x % 2 == 0); // Some(&2)
    let has_negative = numbers.iter().any(|&x| x < 0);       // false

    // zip
    let names = vec!["Alice", "Bob"];
    let ages = vec![25, 30];
    let people: Vec<_> = names.iter().zip(ages.iter()).collect();
    // [("Alice", 25), ("Bob", 30)]

    // enumerate
    for (i, name) in names.iter().enumerate() {
        println!("{}: {}", i, name);
    }

    // flat_map
    let words: Vec<&str> = vec!["hello world", "foo bar"]
        .iter()
        .flat_map(|s| s.split_whitespace())
        .collect();
    // ["hello", "world", "foo", "bar"]
}

3. コレクション

use std::collections::{HashMap, HashSet, BTreeMap};

fn main() {
    // HashMap
    let mut scores: HashMap<&str, i32> = HashMap::new();
    scores.insert("Alice", 95);
    scores.insert("Bob", 87);
    scores.entry("Charlie").or_insert(90); // Insert nếu chưa có

    // Đếm từ
    let text = "hello world hello rust world";
    let mut word_count: HashMap<&str, i32> = HashMap::new();
    for word in text.split_whitespace() {
        *word_count.entry(word).or_insert(0) += 1;
    }

    // HashSet — unique values
    let mut tags: HashSet<String> = HashSet::new();
    tags.insert("rust".into());
    tags.insert("programming".into());

    let other_tags: HashSet<String> = ["rust", "web"].iter().map(|s| s.to_string()).collect();
    let intersection: HashSet<_> = tags.intersection(&other_tags).collect();

    // BTreeMap — sorted keys
    let mut sorted: BTreeMap<String, i32> = BTreeMap::new();
    sorted.insert("c".into(), 3);
    sorted.insert("a".into(), 1);
    // Iteration: a->1, c->3 (sorted)
}

次の記事: エラー処理とモジュール。