Cách thức hoạt động của Smart Pointer trong Rust

Smart Pointer có nhiều ưu điểm hơn so với các con trỏ thông thường. Dưới đây là mọi điều bạn cần biết về Smart Pointer trong Rust.

Cách dùng Smart Pointer trong Rust

Quản lý bộ nhớ là một trong số điểm đáng giá của Rust, đặc biệt ở tính an toàn không bị xâm phạm. Hệ thống sở hữu của Rust cho phép trình biên dịch đảm bảo code an toàn và không bị lỗi bộ nhớ như con trỏ lơ lửng và rò rỉ bộ nhớ.

Rust cũng cung cấp những con trỏ thông minh kèm metadata bổ sung và các tính năng ngoài con trỏ truyền thống. Smart Pointer hữu ích trong việc khắc phục rò rỉ bộ nhớ.

Smart Pointer trong Rust là gì?

Smart Pointer là một trong số các kiểu dữ liệu của Rust, mở rộng tính năng của những con trỏ thông thường bằng cách cung cấp các tính năng bổ sung như toán tử nạp chồng, hàm hủy và quản lý bộ nhớ tự động.

Rust dùng các cấu trúc để chạy những con trỏ thông minh, vì thế, chúng cũng có tính năng sở hữu.

Khi bạn liên kết bộ nhớ chứa dữ liệu được cấp phát động với các con trỏ thông minh, chúng tự động được hủy cấp phát. Những con trỏ thông minh cung cấp tính năng kiểm soát thời gian tồn tại của đối tượng Rust, khiến chúng trở nên hữu ích trong việc ngăn lỗi như dereferencing con trỏ null và rò rỉ bộ nhớ phổ biến ở các ngôn ngữ cấp thấp như C và C++.

Lợi ích khi dùng Smart Pointer

  1. Tự động quản lý bộ nhớ: Smart Pointer cung cấp quản lý bộ nhớ tự động, bao gồm phân bổ và hủy phân bổ, trái ngược với quản lý bộ nhớ ở những con trỏ thông thường.
  2. Cải thiện độ an toàn: Smart Pointer thực thi ngữ nghĩa quyền sở hữu, đảm bảo chỉ một người sở hữu có thể truy cập tài nguyên mỗi lần, ngăn chặn dấu vết dữ liệu và các lỗi liên quan đến đồng quy.
  3. Linh hoạt: Rust cung cấp nhiều con trỏ thông minh, mỗi con trỏ có bộ ngữ nghĩa sở hữu để viết mã an toàn một cách linh hoạt.
  4. Quản lý tài nguyên: Bạn có thể dùng các con trỏ thông minh để quản lý tài nguyên khác như trình xử lý file, socket mạng bằng cách đóng gói tài nguyên trong một con trỏ thông minh để việc quản lý vòng đời của chúng dễ dàng hơn, đồng thời, đảm bảo chúng được đóng và chạy đúng cách sau khi dùng.
  5. Cải thiện hiệu suất: Con trỏ thông minh giúp cải thiện hiệu suất bằng cách giảm sao chép & phân bổ bộ nhớ - giảm dung lượng bộ nhớ nhờ sử dụng con trỏ thông minh giúp tăng hiệu suất.

Smart Pointer phù hợp với các ứng dụng trung bình tới lớn đặc biệt trong trường hợp quản lý bộ nhớ rất quan trọng.

Các kiểu Smart Pointer

Rust cung cấp nhiều kiểu smart pointer, bao gồm Box, Rc, RefCel và Mutex.

Box Smart Pointer

Smart Pointer dạng Box là con trỏ thông minh đơn giản và phổ biến nhất. Con trỏ Box giúp phân bổ giá trị trên heap và tạo một con trỏ được đóng hộp cho khả năng truy cập.

Box Smart Pointer hữu ích trong việc phân bổ bộ nhớ động khi bạn cần đảm bảo bộ nhớ tự động hủy phân bổ lúc con trỏ nằm ngoài phạm vi.

Đây là cách bạn có thể khai báo và dùng con trỏ Box:

fn main(){

    // Phiên bản mới của con trỏ thông minh Box
    let x = Box::new(5);
    println!(x)

}

Kiểu Box là một phần trong phần mở đầu của Rust, vì thế bạn không phải nhập kiểu, khác những con trỏ thông minh khác.

Biễn x là một con trỏ Box trỏ tới 5 giá trị số nguyên. Rust phân bổ bộ nhớ cho giá trị trên heap và tự động hủy phân bổ khi biến nằm ngoài phạm vi.

Rc Smart Pointer

Con trỏ thông minh dạng Rc (Reference Counted) cung cấp tính năng tạo các giá trị của quyền sở hữu chung. Con trỏ thông minh Rc theo dõi số lượng tham chiếu tới một giá trị và hủy phân bổ giá trị khi tham chiếu cuối cùng nằm ngoài phạm vi.

Smart Pointer Rc hữu ích khi bạn cần chia sẻ quyền sở hữu một giá trị cho khả năng truy cập trong nhiều phần của chương trình.

Để khai báo một con trỏ Rc, bạn sẽ nhập cấu trúc Rc từ thư viện chuẩn, khai báo một con trỏ Rc mới với hàm new, nhân bản biến con trỏ bằng biến clone.
use std::rc::Rc;

use std::rc::Rc;

fn main() {

    // new instance of the RC smart pointer 
    let x = Rc::new(5);
    let y = Rc::clone(&x);

    println!("x = {}, y = {}", x, y);
}

Biến x là biến con trỏ Rc, và biến y là một bản sao có quyền truy cập vào giá trị trong bộ nhớ. Bộ đếm tham chiếu là 2, và giá trị được hủy phân bổ từ bộ nhớ khi biến nằm ngoài phạm vi.

Con trỏ Rc

RefCell Smart Pointer

Con trỏ RefCell cung cấp khả năng thay đổi bên trong cho phép các tham chiếu không thể thay đổi và có thể thay đổi cùng tồn tại miễn là có một tham chiếu có thể thay đổi trong mỗi thời điểm nhất định.

Smart Pointer RefCell hữu ích khi các giá trị có thể thay đổi được sở hữu bởi các tham chiếu có thể thay đổi.

Hàm Refcell không phải một phần của mở đầu trong Rust, vì thế, bạn sẽ cần nhập cấu trúc từ thư viện chuẩn để dùng con trỏ thông minh này.

use std::cell::RefCell;

fn main(){

    // new instance of the Refcell smart pointer 
    let x = RefCell::new(5);

    let y = x.borrow();
    let z = x.borrow_mut();

    println!("y = {}", *y);
    println!("z = {}", *z);

} 

Con trỏ thông minh Refcell chứa giá trị này và biến y là tham chiếu bất biến tới giá trị này. Hàm borrow_mut tạo tham chiếu có thể thay đổi của giá trị.

Chương trình này an toàn nếu mỗi lần có một tham chiếu có thể thay đổi.

Mutex Smart Pointer

Con trỏ thông minh Mutex cung cấp khả năng loại trừ lẫn nhau. Smart Pointer Mutex hữu ích trong việc đồng bộ hóa truy cập tới các giá trị trên nhiều luồng trong các chương trình đồng quy.

Con trỏ Mutex cung cấp loại trừ lẫn nhau để đảm bảo chỉ một luồng có thể truy cập giá trị này trong khi ngăn chặn dấu vết dữ liệu.

Bạn sẽ cần nhập cấu trúc Mutex và tạo một phiên bản mới bằng hàm new để dùng Smart Pointer Mutex trong Rust.

use std::sync::Mutex;

fn main() {

    // new instance of the mutex pointer 
    let counter = Mutex::new(0);

    {
        let mut num = counter.lock().unwrap();
        *num += 1;
    }

    println!("Result: {}", *counter.lock().unwrap());
}

Biến counter là một phiên bản Mutex mới. Hàm main yêu cầu một khóa trên mutex với phương thức lock của Mutex. Khóa này cho phép chỉnh sửa giá trị bộ đếm an toàn trước khi phát hành khóa và in giá trị.

Kiểu Mutex đảm bảo chỉ một luồng có thể truy cập những tài nguyên được chia sẻ và chỉnh sửa giá trị của nó tại một thời điểm. Loại trừ lẫn nhau đảm bảo truy cập đồng thời tới các tài nguyên được chia sẻ mà được tuần tự hóa để ngăn dấu vết dữ liệu và các lỗi đồng quy khác.

Con trỏ Mutex trong Rust

Smart Pointer là một trong số cách tiếp cận bộ nhớ an toàn và linh hoạt của Rust. Hi vọng bài viết giúp bạn hiểu rõ hơn về con trỏ thông minh khi lập trình bằng Rust .

Thứ Tư, 31/05/2023 16:36
31 👨 238
0 Bình luận
Sắp xếp theo