Cơ bản về Rust: Biến kiểu dữ liệu, điều khiển luồng và tổ chức mã nguồn

Rust là ngôn ngữ lập trình hệ thống hiện đại với khả năng quản lý bộ nhớ an toàn mà không cần garbage collector. Bài viết này tổng hợp những khái niệm cốt lõi khi bắt đầu làm việc với Rust.

Thiết lập môi trường phát triển

Công cụ quản lý phiên bản chuẩn của Rust là rustup. Cài đặt thông qua terminal:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Sau khi cài đặt, tạo dự án đầu tiên và thực thi:

cargo init --name demo_app
cargo build --release
cargo execute

Cú pháp cơ bản

Rust sử dụng // cho chú thích một dòng và /* */ cho chú thích nhiều dòng. Ký tự thoát được biểu diễn bằng dấu gạch chéo ngược \, ví dụ \n cho xuống dòng hay \t cho tab.

Hệ thống kiểu dữ liệu

Rust phân loại kiểu dữ liệu thành hai nhóm chính: kiểu vô hướng (scalar) và kiểu phức hợp (compound).

Cấu trúc (Struct)

struct cho phép định nghĩa kiểu dữ liệu tùy chỉnh với nhiều trường có kiểu khác nhau:

struct NhanVien {
    ma_so: u32,
    ten: String,
    luong: f64,
    trang_thai: bool,
}

fn tao_nhan_vien() -> NhanVien {
    NhanVien {
        ma_so: 1001,
        ten: String::from("Nguyễn Văn A"),
        luong: 15000000.0,
        trang_thai: true,
    }
}

Bộ dữ liệu (Tuple)

Tuple là tập hợp có độ dài cố định, các phần tử có thể khác kiểu:

let thong_tin: (i32, f64, &str) = (2024, 85.5, "Rust");

Kiểu liệt kê (Enum)

Enum trong Rust là kiểu hợp (sum type) - mỗi biến thể có thể chứa dữ liệu khác nhau:

enum KetQua {
    ThanhCong(String),
    ThatBai { ma_loi: u32, mo_ta: String },
    DangXuLy,
}

Khác với struct (kiểu tích - product type) nơi tất cả trường tồn tại đồng thời, enum chỉ có một biến thể tại một thời điểm.

Điều khiển luồng thực thi

Biểu thức điều kiện

Trong Rust, if là biểu thức trả về giá trị:

fn kiem_tra_diem(diem: u8) -> &'static str {
    let xep_loai = if diem >= 90 {
        "Xuất sắc"
    } else if diem >= 75 {
        "Tốt"
    } else if diem >= 60 {
        "Khá"
    } else {
        "Trung bình"
    };
    xep_loai
}

Các cấu trúc lặp

Rust cung cấp ba cách lặp: loop (vô hạn), while (điều kiện), và for (duyệt iterator).

Toán tử .. tạo range, ..= bao gồm cả giá trị cuối:

for chi_so in 0..5 {
    println!("{}", chi_so); // 0, 1, 2, 3, 4
}

for chi_so in 0..=5 {
    println!("{}", chi_so); // 0, 1, 2, 3, 4, 5
}

Hàm và closure

Định nghĩa hàm

Hàm trong Rust khai báo rõ ràng kiểu tham số và kiểu trả về:

fn tinh_dien_tich(chieu_dai: f64, chieu_rong: f64) -> f64 {
    chieu_dai * chieu_rong  // Không cần return, không có dấu chấm phẩy
}

Closure

Closure là hàm ẩn danh có thể bắt biến từ phạm vi bên ngoài:

let he_so = 10;
let nhan_he_so = |gia_tri: i32| -> i32 {
    gia_tri * he_so
};

println!("Kết quả: {}", nhan_he_so(5)); // 50

Tổ chức mã nguồn

Rust sử dụng module để phân chia code. Cấu trúc thư mục chuẩn:

du_an/
├── Cargo.lock
├── Cargo.toml
└── src/
    ├── main.rs          // Điểm vào chương trình
    ├── thu_vien.rs      // Module gốc
    └── thu_vien/        // Thư mục con module
        ├── mod.rs       // Hoặc thu_vien.rs ở cấp trên
        ├── cong_cu.rs
        └── tien_ich.rs

File cùng tên với thư mục module đóng vai trò entry point.

Khái niệm quan trọng: Sized

Một đặc điểm quan trọng của Rust là khả năng xác định kích thước bộ nhớ của kiểu dữ liệu tại thời điểm biên dịch. Các kiểu thỏa mãn Sized trait có kích thước cố định, cho phép cấp phát trên stack. Các kiểu động như slice ([T]) hoặc trait object (dyn Trait) không thỏa mãn Sized và phải thông qua tham chiếu (&[T]) hoặc smart pointer (Box<dyn Trait>).

Thẻ: Rust Ownership struct enum closure

Đăng vào ngày 23 tháng 9 lúc 08:41