Destructuring

Mari kita lihat lebih lanjut tentang destructuring. Anda bisa mendapatkan value dari struct atau enum dengan menggunakan let secara terbalik. Kita telah mempelajari bahwa hal seperti ini disebut sebagai destructuring, karena nantinya kita akan mendapatkan variable yang mana adalah bukan bagian dari struktur (entah struktur tersebut adalah struct atau enum). Atau dengan kata lain, kita mendapatkan valuenya secara terpisah. Berikut adalah contohnya:

struct Person { // membuat struct sederhana untuk person
    name: String,
    real_name: String,
    height: u8,
    happiness: bool
}

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

    let Person { // destructure 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);
}

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

Bisa kita lihat, kita menggunakan let secara terbalik. Pertama, kita menuliskan let papa_doc = Person { fields } untuk membuat sebuah struct. kemudian kita menuliskan let Person { fields } = papa_doc untuk melakukan destructure pada papa_doc.

Anda tidak perlu menuliskan name: a - Anda cukup menuliskan name. Tapi disini kita menulis name: a karena kita ingin menggunakan variabel dengan nama a.

Kita masuk ke contoh yang lebih besar dari sebelumnya. Pada contoh kali ini kita memiliki struct City. Kita berikan implementasikan function new untuk membuatnya. Kemudian kita memiliki function process_city_values untuk melakukan sesuatu terhadap valuenya. Di dalam function tersebut, kita hanya membuat sebuah Vec, namun Anda bisa lihat bahwa kita bisa melakukan banyak hal setelah kita melakukan destructure kepada parameter city.

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;
        // sekarang kita memiliki value yang digunakan secara terpisah
    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);
}

Dan hasilnya adalah The city's two names are ["Tallinn", "Reval"].