解構

我們再來多看些解構(destructuring)。你可以反過來透過使用 let 從結構體或列舉中獲取值。我們瞭解到這是 destructuring,因為你得到的變數不是結構體的一部分。現在你分別得到了它們的值。首先是一個簡單的範例:

struct Person { // 為個人資料做一個簡單的結構體
    name: String,
    real_name: String,
    height: u8,
    happiness: bool
}

fn main() {
    let papa_doc = Person { // 建立變數 papa_doc
        name: "Papa Doc".to_string(),
        real_name: "Clarence".to_string(),
        height: 170,
        happiness: false
    };

    let Person { // 解構 papa_doc
        name: a,
        real_name: b,
        height: c,
        happiness: d
    } = papa_doc;

    println!("They call him {} but his real name is {}. He is {} cm tall and is he happy? {}", a, b, c, d);
}

印出:They call him Papa Doc but his real name is Clarence. He is 170 cm tall and is he happy? false

你可以看到它是反過來的。首先我們說 let papa_doc = Person { fields } 來建立結構體。然後我們說 let Person { fields } = papa_doc 來解構它。

你不必寫 name: a──你可以直接寫 name。但這裡我們寫 name: a 是因為我們想使用一個名字為 a 的變數。

現在再舉一個更大的例子。在這個例子中,我們有一個 City 結構體。我們給它一個 new 函式來做出它。然後我們有一個 process_city_values 函式來處理這些值。在函式中,我們只是建立了一個 Vec,但你可以想象,我們可以在解構它之後做更多的事情。

struct City {
    name: String,
    name_before: String,
    population: u32,
    date_founded: u32,
}

impl City {
    fn new(name: String, name_before: String, population: u32, date_founded: u32) -> Self {
        Self {
            name,
            name_before,
            population,
            date_founded,
        }
    }
}

fn process_city_values(city: &City) {
    let City {
        name,
        name_before,
        population,
        date_founded,
    } = city;
        // 現在我們有可分別使用的值了
    let two_names = vec![name, name_before];
    println!("The city's two names are {:?}", two_names);
}

fn main() {
    let tallinn = City::new("Tallinn".to_string(), "Reval".to_string(), 426_538, 1219);
    process_city_values(&tallinn);
}

印出 The city's two names are ["Tallinn", "Reval"]