Struct เป็นประเภทของโครงสร้างข้อมูลที่เหมือนกัน Tuples Types ที่ทำหน้าที่เก็บข้อมูลที่ที่แตกต่างกัน ตัว Struct จะต่างจาก tuples คือ ใน struct นั้น เราจะต้องตั้งชื่อข้อมูลแต่ละส่วนให้ชัดเจนว่าค่านั้นหมายถึงอะไร

Basic

วิธีการสร้าง struct นั้นเราจะใช้ struct เป็นคำนำหน้า โดยที่ภายใน {} นั้นเราจะประกาศประเภทของข้อมูล แบบไหนก็ได้แล้วแต่เราเลย

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}

struct

หากต้องการกำหนดค่าให้แก่ตัวแปร

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}
    
fn main() {
    let user1 = User {
        active: true,
        username: String::from("jaranchai"),
        email: String::from("[email protected]"),
        sign_in_count: 1,
    };

    println!("Username: {}", user1.username);
    println!("Email: {}", user1.email);
    println!("Sign in count: {}", user1.sign_in_count);
    println!("Active: {}", user1.active);
}

example struct

การเข้าถึงข้อมูลเราสามารถเข้าถึงข้อมูลแต่ละตัวได้โดยการอ้างอิงชื่อตัวแปรภายในเลย user1.email

เช่นเดียวกันกับการแก้ไขข้อมูลภายใน เราก็ใช้วิธีเดียวกัน (อย่าลืมเพิ่ม mut หลัง let)

user1.email = String::from("[email protected]");

assign new value


Creating Instances from Other Instances

เรายังสามารถสร้างข้อมูลใหม่ โดยใช้ข้อมูลจาก struct ตัวอื่นได้ และสามารถเลือกที่จะแก้ไขข้อมูลบางตัวได้

fn main() {
    let mut user1 = User {
        active: true,
        username: String::from("jaranchai"),
        email: String::from("[email protected]"),
        sign_in_count: 1,
    };

    let user2 = User {
        active: user1.active,
        username: user1.username,
        email: String::from("[email protected]"),
        sign_in_count: user1.sign_in_count,
    };
}

create new variable and instance from other instance

เพื่อให้เราเขียนโค๊ดได้สั้นลง เราอาจใช้วิธีระบุ ..user1 และเลือกเปลี่ยนเฉพาะบางตัว

fn main() {
    let mut user1 = User {
        active: true,
        username: String::from("jaranchai"),
        email: String::from("[email protected]"),
        sign_in_count: 1,
    };

    let user2 = User {
        email: String::from("[email protected]"),
        ..user1
    };
}

create new instance by ..

Struct with Tuples

เราสามารถใช้งาน struct รวมกันกับ tuples ได้ด้วยเช่นกัน

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

fn main() {
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
}

Struct with tuples

หากต้องการอัพเดทข้อมูลสามารถทำได้ทั้งแบบ แก้ไขทั้งหมด และแก้ไขเฉพาะบางตัว

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

fn main() {
    let mut black = Color(0, 0, 0);

    black.0 = 255;

    // or

    black = Color(255, 255, 255);
}

update data in variable


Method Syntax

เราสามารถเพิ่ม method เข้าไปใน struct ด้วยเลยก็ได้ โดยเราจะเพิ่ม impl และเพิ่มการทำงาน method เข้าไป

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()
    );
}

method syntex

การเรียกใช้งาน ก็เป็นการอ้างอิงถึงข้อมูล และ method rect1.area() ที่ต้องการได้เลย

หากต้องการใช้ ใช้ค่าใช้ struct นั้น เราจะใช้ผ่านตัวแปร &self ในการเข้าถึงค่าในตัวของ struct เอง คล้ายๆ กับการใช้ this ในภาษา java เลย

อีกอย่าง เราสามารถที่จะสร้างหลายๆ impl ได้ด้วย

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

impl Rectangle {
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}

Multiple impl Block