Tuples

Tipe data tuples

// contoh fungsi yang return tuples
fn coordinate() -> (i32, i32) {
    (1, 7)
}
fn main() {
    // destructive
    let (x, y) = coordinate();
    println!("x:{x} y:{y}");
}

Struct

struct GroceryItem {
    qty: i32,
    id: i32,
}
fn display_item(item: GroceryItem) {
    println!("result: qty {} id {}", item.qty, item.id)
}
fn main() {
    let data = GroceryItem { qty: 30, id: 23 };
    // println!("result: {data}");
    display_item(data);
}

Expression

fn main() {
    // ex1:
    let my_num = 3;
    let is_lt_5 = if my_num < 5 { true } else { false };
    print!("hasil: {is_lt_5}");

    let is_lt_5_carake_2 = my_num > 5;
    print!("hasil 2: {is_lt_5_carake_2}");

    // ex2:
    let my_n = 3;
    let message = match my_n {
        1 => "hello",
        _ => "goodbye",
    };
    print!("hasil 3: {message}");
}

Ownership

Ex1 : error karena data ownership dipindah kan ke fungsi

enum Light {
    Bright,
    Dull,
}
fn display_light(light: Light) {
    //gunakan & atau borrow agar tidak dipindahkan dan bisa dipanggil beberapa kali
    match light {
        Light::Bright => print!("bright"),
        Light::Dull => print!("dull"),
    }
}

fn main() {
    let dull = Light::Dull;
    display_light(dull);
    display_light(dull); //erro karen dull telah dipindahkan ke fungsi display_light
}

Ex1 solusi,, gunakan & untuk borrowing dan dapat dipanggil lagi

enum Light {
    Bright,
    Dull,
}
fn display_light(light: &Light) {
    //gunakan & atau borrow agar tidak dipindahkan dan bisa dipanggil beberapa kali, & berarti mereferensikan
    match light {
        Light::Bright => print!("bright"),
        Light::Dull => print!("dull"),
    }
}

fn main() {
    let dull = Light::Dull;
    display_light(&dull);
    display_light(&dull); //erro karen dull telah dipindahkan ->//gunakan & atau borrow agar tidak dipindahkan dan bisa dipanggil beberapa kali
}

Implement / impl

The impl keyword is primarily used to define implementations on types. Inherent implementations are standalone, while trait implementations are used to implement traits for types, or other traits.

Functions and consts can both be defined in an implementation. A function defined in an impl block can be standalone, meaning it would be called like Foo::bar(). If the function takes self&self, or &mut self as its first argument, it can also be called using method-call syntax, a familiar feature to any object oriented programmer, like foo.bar().

#![allow(non_snake_case)]
struct Temperatur {
    degrees_f: f64,
}
impl Temperatur {
    // fn freezing() -> Temperatur {
    //     Temperatur { degrees_f: 32.0 }
    // }
    fn freezing() -> Self {
        Self { degrees_f: 32.0 }
    }
    fn show_temp(&self) {
        println!("{} degrees F", self.degrees_f)
    }
}
fn main() {
    let hot = Temperatur { degrees_f: 9.99 };
    // TemperatureData::show_temp(hot)
    hot.show_temp();
    let cold = Temperatur::freezing();
    cold.show_temp()
}