2k1
  • Home
  • Programming
  • System
  • Design
  • Applications
  • Tech
No Result
View All Result
  • Login
2k1
  • Home
  • Programming
  • System
  • Design
  • Applications
  • Tech
No Result
View All Result
2k1
No Result
View All Result

Lập trình Rust Cơ Bản: Khám Phá Struct – Sức Mạnh Của Kiểu Dữ Liệu Tùy Chỉnh

Nguyen Pham by Nguyen Pham
01/01/2026
in Blog
Reading Time: 9 mins read
A A
0

Lập trình Rust Cơ Bản: Khám Phá Struct – Sức Mạnh Của Kiểu Dữ Liệu Tùy Chỉnh

Chào mừng bạn đến với hành trình khám phá thế giới Rust! Nếu bạn đã quen thuộc với các khái niệm cơ bản như biến, hàm, và kiểu dữ liệu nguyên thủy, thì đây là lúc để chúng ta nâng tầm khả năng lập trình Rust của mình bằng cách tìm hiểu về một trong những tính năng mạnh mẽ nhất: Struct. Struct cho phép chúng ta định nghĩa các kiểu dữ liệu tùy chỉnh, gói gọn các thông tin liên quan lại với nhau, giúp code của bạn trở nên có tổ chức, dễ đọc và dễ bảo trì hơn rất nhiều. Hãy cùng nhau đi sâu vào khám phá cách Struct hoạt động trong Rust nhé!

Struct trong Rust là gì?

Trong Rust, Struct (viết tắt của “structure”) là một cách để tạo ra các kiểu dữ liệu tùy chỉnh bằng cách nhóm một số giá trị liên quan với nhau. Tưởng tượng như bạn đang tạo một “bản thiết kế” để mô tả một thực thể trong thế giới thực, chẳng hạn như một người dùng, một hình chữ nhật, hoặc một sản phẩm. Mỗi “bản thiết kế” này sẽ có các “trường” (fields) riêng biệt để lưu trữ các thuộc tính của thực thể đó.

Struct tương tự như các lớp (classes) trong các ngôn ngữ hướng đối tượng khác nhưng không có các khái niệm về kế thừa hay đa hình theo cách truyền thống. Chúng chủ yếu tập trung vào việc tổ chức dữ liệu.

So sánh Struct với Tuple

  • Tuple: Nhóm các giá trị lại với nhau nhưng các trường không có tên, chúng ta truy cập thông qua chỉ số (ví dụ: `tuple.0`, `tuple.1`). Điều này có thể gây khó đọc nếu tuple có nhiều phần tử.
  • Struct: Nhóm các giá trị lại với nhau và mỗi giá trị có một tên trường rõ ràng (ví dụ: `user.username`, `rectangle.width`). Điều này giúp code dễ đọc và dễ hiểu hơn nhiều.

Định nghĩa một Struct cơ bản

Để định nghĩa một Struct, chúng ta sử dụng từ khóa `struct`, theo sau là tên của struct và một cặp dấu ngoặc nhọn `{}` chứa các trường của nó. Mỗi trường có một tên và một kiểu dữ liệu.


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

Trong ví dụ trên, chúng ta định nghĩa một `struct User` với bốn trường: `username` (kiểu `String`), `email` (kiểu `String`), `sign_in_count` (kiểu `u64`), và `active` (kiểu `bool`).

Tạo và truy cập Instance của Struct

Sau khi đã định nghĩa Struct, chúng ta có thể tạo ra các “thể hiện” (instance) cụ thể của nó và truy cập các trường dữ liệu bên trong.


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

    println!("Tên người dùng: {}", user1.username);
    println!("Email: {}", user1.email);

    // Lưu ý: Nếu muốn thay đổi giá trị của một trường, instance phải là mutable
    let mut user2 = User {
        email: String::from("[email protected]"),
        username: String::from("anotheruser"),
        active: true,
        sign_in_count: 1,
    };

    user2.email = String::from("[email protected]");
    println!("Email mới của user2: {}", user2.email);
}
            

Để truy cập một trường trong Struct, chúng ta sử dụng cú pháp dấu chấm (`.`) theo sau là tên trường. Để một instance của Struct có thể thay đổi được, bạn cần khai báo nó với từ khóa `mut`.

Cú pháp rút gọn khi khởi tạo Struct (Field Init Shorthand)

Nếu tên biến dùng để khởi tạo trường Struct trùng với tên trường, bạn có thể sử dụng cú pháp rút gọn.


fn build_user(email: String, username: String) -> User {
    User {
        email,       // Rút gọn từ email: email,
        username,    // Rút gọn từ username: username,
        active: true,
        sign_in_count: 1,
    }
}
            

Cú pháp cập nhật Struct (Struct Update Syntax)

Khi bạn muốn tạo một instance Struct mới dựa trên một instance hiện có, nhưng chỉ thay đổi một vài giá trị, bạn có thể sử dụng cú pháp cập nhật Struct. Điều này giúp tránh việc lặp lại code.


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

    let user3 = User {
        email: String::from("[email protected]"),
        ..user1 // Lấy các giá trị còn lại từ user1
    };

    println!("Username của user3: {}", user3.username); // someusername123
    println!("Email của user3: {}", user3.email);     // [email protected]
}
            

Các loại Struct khác: Tuple Struct và Unit-Like Struct

Tuple Struct

Tuple Struct tương tự như Tuple nhưng có một tên định danh. Chúng hữu ích khi bạn muốn đặt tên cho một tuple và đảm bảo rằng các tuple cùng loại được coi là cùng một kiểu, nhưng các trường không cần tên cụ thể.


struct Color(i32, i32, i32); // RGB
struct Point(i32, i32, i32); // 3D coordinates

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

    // Dù có cùng kiểu dữ liệu bên trong, chúng là các kiểu riêng biệt
    // let x = black.0 + origin.0; // Lỗi biên dịch: không thể cộng Color với Point
}
            

Unit-Like Struct

Đây là những Struct không có bất kỳ trường nào. Chúng thường được sử dụng khi bạn cần triển khai một trait trên một kiểu nhưng không có dữ liệu nào để lưu trữ trong kiểu đó. Chúng có hành vi tương tự như `()` (unit type) nhưng có một tên cụ thể.


struct AlwaysEqual;

fn main() {
    let subject = AlwaysEqual;
    // Không có trường nào để truy cập
}
            

Struct và Method: Nâng cao khả năng của kiểu dữ liệu tùy chỉnh

Điểm mạnh thực sự của Struct không chỉ nằm ở việc nhóm dữ liệu, mà còn ở khả năng định nghĩa các method (phương thức) và associated function (hàm liên kết) cho chúng. Điều này cho phép bạn thêm hành vi vào kiểu dữ liệu tùy chỉnh của mình.

Chúng ta sử dụng khối `impl` (implementation) để định nghĩa các method cho Struct.


struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // Một method: tính diện tích
    fn area(&self) -> u32 {
        self.width * self.height
    }

    // Một associated function (không lấy &self)
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

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

    println!("Diện tích hình chữ nhật: {} px", rect1.area()); // Gọi method

    let sq = Rectangle::square(25); // Gọi associated function
    println!("Diện tích hình vuông: {} px", sq.area());
}
            

  • Method: Là các hàm được định nghĩa trong khối `impl` và lấy một tham chiếu đến instance của Struct (`&self`, `&mut self`, hoặc `self`) làm đối số đầu tiên. Chúng được gọi bằng cú pháp dấu chấm (`.`) trên một instance (ví dụ: `rect1.area()`).
  • Associated Function: Cũng được định nghĩa trong khối `impl` nhưng không lấy `&self`. Chúng giống như các “hàm tĩnh” trong các ngôn ngữ khác và thường được dùng để tạo ra các instance mới của Struct (constructor). Chúng được gọi bằng cú pháp hai dấu chấm (`::`) trên tên Struct (ví dụ: `Rectangle::square(25)`).

Khi nào nên sử dụng Struct?

Struct là lựa chọn tuyệt vời khi bạn cần:

  • Tổ chức dữ liệu liên quan: Thay vì truyền nhiều tham số riêng lẻ vào hàm, hãy nhóm chúng vào một Struct duy nhất.
  • Tạo kiểu dữ liệu có ý nghĩa: Đặt tên rõ ràng cho các tập hợp dữ liệu giúp code dễ đọc và tự giải thích.
  • Thêm hành vi cho dữ liệu: Sử dụng method để gắn các hành động cụ thể với dữ liệu của Struct.
  • Đảm bảo an toàn kiểu dữ liệu: Rust sẽ kiểm tra kiểu dữ liệu của các trường Struct tại thời điểm biên dịch, giúp bạn tránh các lỗi logic.

Kết luận

Struct là một khối xây dựng cơ bản và cực kỳ quan trọng trong lập trình Rust, giúp bạn tạo ra các kiểu dữ liệu tùy chỉnh có cấu trúc và ý nghĩa. Bằng cách sử dụng Struct, bạn có thể tổ chức code một cách hiệu quả, làm cho ứng dụng của mình dễ hiểu, dễ mở rộng và dễ bảo trì hơn. Từ việc định nghĩa một Struct đơn giản cho đến việc thêm các method và associated function, bạn đã có trong tay công cụ mạnh mẽ để xây dựng các chương trình Rust phức tạp hơn.

Hãy thực hành thật nhiều với Struct để nắm vững khái niệm này. Trong các bài viết tiếp theo, chúng ta sẽ cùng nhau khám phá thêm nhiều khía cạnh thú vị khác của Rust. Chúc bạn lập trình vui vẻ!

Previous Post

Chứng Khoán và Tài Chính: Chìa Khóa Mở Cánh Cửa Thịnh Vượng Cá Nhân và Doanh Nghiệp

Related Posts

Chứng Khoán và Tài Chính: Chìa Khóa Mở Cánh Cửa Thịnh Vượng Cá Nhân và Doanh Nghiệp
Blog

Chứng Khoán và Tài Chính: Chìa Khóa Mở Cánh Cửa Thịnh Vượng Cá Nhân và Doanh Nghiệp

by Nguyen Pham
17/11/2025
Chứng Khoán Và Tài Chính: Cánh Cửa Mở Ra Tương Lai Thịnh Vượng Của Bạn
Blog

Chứng Khoán Và Tài Chính: Cánh Cửa Mở Ra Tương Lai Thịnh Vượng Của Bạn

by Nguyen Pham
17/11/2025
GitHub Codespaces là gì? Môi Trường Phát Triển Đám Mây Đỉnh Cao Cho Dev
Blog

GitHub Codespaces là gì? Môi Trường Phát Triển Đám Mây Đỉnh Cao Cho Dev

by Nguyen Pham
17/11/2025
Lập trình Rust Cơ Bản: Khám Phá Tuple – Bộ Sưu Tập Dữ Liệu Đa Kiểu Mạnh Mẽ
Blog

Lập trình Rust Cơ Bản: Khám Phá Tuple – Bộ Sưu Tập Dữ Liệu Đa Kiểu Mạnh Mẽ

by Nguyen Pham
16/11/2025
Lập trình Rust Cơ Bản: Nắm Vững Kiểu Dữ Liệu Mảng – Khởi Đầu Vững Chắc!
Blog

Lập trình Rust Cơ Bản: Nắm Vững Kiểu Dữ Liệu Mảng – Khởi Đầu Vững Chắc!

by Nguyen Pham
16/11/2025
Lập trình Rust Cơ Bản: Nắm Vững Câu Lệnh Điều Kiện If/Else và Match
Blog

Lập trình Rust Cơ Bản: Nắm Vững Câu Lệnh Điều Kiện If/Else và Match

by Nguyen Pham
16/11/2025
Load More
Please login to join discussion

@2021 2k1.org [email protected]

No Result
View All Result
  • Home
  • Review
  • Applications
  • Computers
  • Gaming
  • Microsoft

© 2021 NData

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In