Rust Notes #2: References và Borrowing

Author

Thâm / December 28, 2024

3 min read––– lượt xem

Giới thiệu về References

Reference (tham chiếu) trong Rust là một khái niệm quan trọng, cho phép bạn truy cập dữ liệu mà không cần lấy quyền sở hữu (ownership).

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);    // Truyền tham chiếu của s1
    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

Đặc điểm của References:

  • Tương tự như con trỏ, reference là một địa chỉ trỏ đến dữ liệu
  • Đảm bảo trỏ đến giá trị hợp lệ trong suốt vòng đời của reference
  • Không có quyền sở hữu dữ liệu mà nó trỏ đến

Borrowing

Borrowing (mượn) là hành động tạo một reference. Giống như trong đời thực:

  • Bạn mượn một thứ gì đó từ người khác
  • Khi dùng xong, bạn phải trả lại
  • Bạn không sở hữu nó

Quy tắc cơ bản:

  1. Mặc định references là immutable (không thể thay đổi giá trị)
  2. Không thể thay đổi giá trị thông qua immutable reference
fn main() {
    let s = String::from("hello");
    change(&s);    // Không thể thay đổi giá trị qua immutable reference
}

fn change(some_string: &String) {
    some_string.push_str(", world");    // Lỗi!
}

Mutable References

Để cho phép thay đổi giá trị thông qua reference, ta sử dụng mutable reference:

fn main() {
    let mut s = String::from("hello");
    change(&mut s);    // Tạo mutable reference
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");    // OK!
}

Giới hạn của Mutable References:

  1. Chỉ có thể có một mutable reference tại một thời điểm
  2. Không thể có mutable reference khi đã có immutable references
  3. Các references phải có scope hợp lệ
let mut s = String::from("hello");

let r1 = &mut s;    // OK - mutable reference đầu tiên
let r2 = &mut s;    // Lỗi - không thể có mutable reference thứ hai

Dangling References

Rust ngăn chặn dangling references - references trỏ đến bộ nhớ đã bị giải phóng:

fn dangle() -> &String {    // Lỗi!
    let s = String::from("hello");
    &s    // s sẽ bị giải phóng khi hàm kết thúc
}        // reference trở thành dangling

Giải pháp: Trả về giá trị trực tiếp thay vì reference:

fn no_dangle() -> String {
    let s = String::from("hello");
    s    // Chuyển ownership ra ngoài
}

Lợi ích của hệ thống References

  1. An toàn bộ nhớ: Ngăn chặn data races và dangling references tại thời điểm biên dịch
  2. Hiệu quả: Không cần copy dữ liệu khi chỉ cần đọc hoặc thay đổi tạm thời
  3. Kiểm soát: Quy tắc chặt chẽ về mutable/immutable references giúp code an toàn hơn

References và Borrowing là những khái niệm cốt lõi trong Rust, giúp đảm bảo an toàn bộ nhớ mà vẫn duy trì hiệu năng cao.

Đăng ký nhận thông báo qua email khi có bài viết mới

0 người đăng ký