- vừa được xem lúc

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

0 0 4

Người đăng: Hoang Minh Dai

Theo Viblo Asia


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

Bình luận

Bài viết tương tự

- vừa được xem lúc

Chuyện cái comment

Chuyện cái comment. Chuyện rằng, có một ông bạn nọ có cái blog ở trên mạng, cũng có dăm.

0 0 36

- vừa được xem lúc

Đừng đánh nhau với borrow checker

Đừng đánh nhau với borrow checker. TL;DR: Đừng bao giờ đánh nhau với borrow checker, nó được sinh ra để bạn phải phục tùng nó .

0 0 31

- vừa được xem lúc

Chuyện biểu diễn ma trận trên máy tính

Chuyện biểu diễn ma trận trên máy tính. Cách đây mấy hôm mình có share cái screenshot trên Facebook, khoe linh tinh vụ mình đang viết lại cái CHIP-8 emulator bằng Rust.

0 0 45

- vừa được xem lúc

Rust và Lập trình Web

Rust và Lập trình Web. Bài viết được dịch lại từ bản gốc "Rust for the Web" đăng tại phiên bản blog tiếng Anh của mình.

0 0 40

- vừa được xem lúc

Viết ứng dụng đọc tin HackerNews bằng Rust

Viết ứng dụng đọc tin HackerNews bằng Rust. Dạo này mình toàn viết bài linh tinh, lâu rồi chưa thấy viết bài kĩ thuật nào mới nên hôm nay mình viết trở lại, mất công các bạn lại bảo mình không biết co

0 0 28

- vừa được xem lúc

Cài đặt Rust trên Arch Linux

Cài đặt Rust trên Arch Linux. Việc cài đặt Rust trên môi trường Arch Linux khá là đơn giản.

0 0 46