0

Lập trình Rust cơ bản và nâng cao


I.🦀 Giới thiệu tổng quan về Rust

  • Rust là ngôn ngữ lập trình hệ thống được phát triển bởi Mozilla Research.
  • Ra mắt lần đầu năm 2010, chính thức ổn định từ bản 1.0 (2015).
  • Mục tiêu: hiệu năng cao như C/C++ nhưng an toàn về bộ nhớ, không có lỗi null hay data race, và có hệ thống kiểm tra kiểu mạnh mẽ.

🔧 Tính năng nổi bật

1. Memory Safety mà không cần Garbage Collector

Rust không dùng Garbage Collector (GC) như Java hay Go, mà thay vào đó dùng:

  • Ownership (Sở hữu): mỗi giá trị có một chủ sở hữu duy nhất.
  • Borrowing (Mượn): cho phép tham chiếu tạm thời mà không chiếm quyền sở hữu.
  • Lifetimes (Vòng đời): xác định rõ thời gian sống của các tham chiếu để tránh dangling pointer.

2. Concurrency an toàn

  • Rust ngăn chặn data races ở compile-time.
  • Hỗ trợ mô hình thread-safe, message passing (qua channels), và async/await.

3. Pattern Matching và Enums mạnh mẽ

  • Enums có thể chứa dữ liệu (sum types), kết hợp pattern matching giúp code rõ ràng và an toàn.

4. Performance tối ưu

  • Biên dịch ra mã máy (native) nên nhanh như C/C++.
  • Không có runtime overhead nếu bạn không cần.

5. Hệ thống Module và Crate

  • Crate là đơn vị gói nhỏ (như package).
  • Cargo – công cụ build/package chính thức.

🛠 Cấu trúc cơ bản

Hello World

fn main() {
    println!("Hello, world!");
}

Biến và kiểu dữ liệu

let x = 5;          // immutable
let mut y = 10;     // mutable
let z: f64 = 3.14;  // khai báo kiểu rõ ràng

Ownership & Borrowing

fn main() {
    let s = String::from("hello");
    takes_ownership(s); // s bị move, không còn dùng được
    // println!("{}", s); // lỗi biên dịch
}

fn takes_ownership(s: String) {
    println!("{}", s);
}
fn borrow_example(s: &String) {
    println!("{}", s); // borrow, không move
}

🧱 Kiến trúc chương trình

Struct và Impl

struct Person {
    name: String,
    age: u8,
}

impl Person {
    fn greet(&self) {
        println!("Hi, my name is {}", self.name);
    }
}

Enum và Match

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
}

fn process(msg: Message) {
    match msg {
        Message::Quit => println!("Quit"),
        Message::Move { x, y } => println!("Move to ({}, {})", x, y),
        Message::Write(s) => println!("Write {}", s),
    }
}

🌐 Async/Concurrency

Async/await

async fn fetch_data() -> String {
    "data".to_string()
}

#[tokio::main]
async fn main() {
    let result = fetch_data().await;
    println!("Result: {}", result);
}

Channels & Threads

use std::thread;
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        tx.send("Hello").unwrap();
    });

    println!("Got: {}", rx.recv().unwrap());
}

📦 Cargo – công cụ quản lý dự án

Tạo dự án mới

cargo new my_project
cd my_project
cargo build
cargo run

Thêm thư viện (crate)

# trong Cargo.toml
[dependencies]
serde = "1.0"
tokio = { version = "1", features = ["full"] }

🧪 Kiểm thử trong Rust

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(2 + 2, 4);
    }
}

📚 Học thêm


II. Các chủ đề nâng cao, kết hợp với phân tích chi tiếtcác kỹ thuật thực chiến


🧠 1. Hệ thống Ownership & Lifetimes nâng cao

Move Semantics & Copy Types

  • Copy: primitive types như i32, bool, f64, char (không cấp phát heap).
  • Các struct chỉ có các trường kiểu Copy mới được Copy.
#[derive(Copy, Clone)]
struct Point(i32, i32);

Borrowing nâng cao

  • Một biến có thể có nhiều immutable references hoặc một mutable reference, không đồng thời.
fn mutate(s: &mut String) {
    s.push_str(" world");
}

Explicit Lifetimes

  • Khi compiler không thể suy ra vòng đời, cần chỉ rõ 'a, 'b,…
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

🧰 2. Trait, Generics & Trait Bounds

Generics

fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest = &list[0];
    for item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

Trait & Trait Bound nâng cao

trait Summarizable {
    fn summary(&self) -> String;
}

struct Article { title: String }

impl Summarizable for Article {
    fn summary(&self) -> String {
        format!("Article: {}", self.title)
    }
}

Blanket Implementations

impl<T: Display> ToString for T {
    // tất cả kiểu có Display đều có ToString
}

🕸 3. Async/Await, Tokio, và Future nâng cao

Futures là gì?

  • Future là trait, biểu diễn 1 giá trị chưa có sẵn, sẽ được tính toán bất đồng bộ.
  • async fn trả về impl Future.
use tokio::time::sleep;
use std::time::Duration;

async fn delay_hello() {
    sleep(Duration::from_secs(1)).await;
    println!("Hello after 1s");
}

Concurrency vs Parallelism

  • Concurrency (async): cùng lúc nhiều tác vụ logic (sử dụng 1 thread).
  • Parallelism: nhiều thread xử lý cùng lúc (đa luồng).

Pinning & Unwind Safety (nâng cao async)

  • Pin<&mut T> bảo đảm địa chỉ không đổi khi future đang pending.
  • Rất quan trọng với async trait + generator (đặc biệt khi làm executor).

🧱 4. Unsafe Rust & Low-level control

Khi nào dùng unsafe?

  • Giao tiếp với C (extern "C").
  • Truy cập raw pointer.
  • Gọi FFI.
  • Giao tiếp với OS hoặc viết system-level (e.g., kernel, driver).
unsafe {
    let ptr = 0x12345 as *const i32;
    println!("val: {}", *ptr);
}

Dù Rust an toàn mặc định, unsafe cho phép làm việc gần máy nhưng vẫn phải đảm bảo logic an toàn.


📦 5. Hệ thống Module, Crate và Macro nâng cao

Crate-level visibility

pub(crate) fn only_in_this_crate() {}

Procedural Macros

  • Custom derive, function-like macro, attribute macro.
#[derive(Debug)]
struct MyStruct;

#[proc_macro]
pub fn my_macro(input: TokenStream) -> TokenStream { ... }

🔄 6. Memory Management, Zero-cost Abstractions

Box, Rc, Arc, Cell, RefCell

Loại Ý nghĩa Ghi chú
Box<T> heap allocation ownership chuyển đơn
Rc<T> reference counted không thread-safe
Arc<T> atomic reference counted thread-safe
RefCell<T> borrow checker runtime dùng cho nội bộ
Cell<T> mutable copy dùng cho kiểu Copy

🗂 7. Lập trình hướng hệ thống / OS

  • Viết hệ điều hành (RustOS): sử dụng no_std, bootloader, x86_64 crate.
  • Direct memory access: map buffer từ hardware.
#![no_std]
#![no_main]

use core::panic::PanicInfo;

#[no_mangle]
pub extern "C" fn _start() -> ! {
    loop {}
}

📊 8. Xử lý dữ liệu, Web backend, WASM, ML với Rust

Web: Axum / Actix-web

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(|| async { "Hello" }));
    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await.unwrap();
}

Xử lý dữ liệu: Polars, Arrow, DuckDB

  • Polars: giống Pandas nhưng nhanh và an toàn.
  • DuckDB: nhúng C++ engine nhưng thao tác từ Rust dễ dàng.
  • Giao tiếp qua ndarray, rayon, arrow2.

📚 Tài liệu học nâng cao

Chủ đề Tài liệu
Tất cả The Rustonomicon
Async Async Book
Unsafe Unsafe Code Guidelines
Lập trình hệ thống Writing an OS in Rust
Polars/Arrow Polars Docs


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí