Con trỏ thông minh và các đặc trưng Deref cùng Drop trong Rust

Box<T>

Box<T> là con trỏ thông minh sở hữu dữ liệu độc quyền trong Rust:

let value = Box::new(10);
println!("Giá trị = {}", value);

enum DanhSách {
    Nút(i32, Box<DanhSách>),
    KếtThúc,
}

use DanhSách::{Nút, KếtThúc};
let ds = Nút(1,
    Box::new(Nút(2,
        Box::new(Nút(3,
            Box::new(KếtThúc))))));

let a = 8;
let b = &a;
let c = Box::new(a);
assert_eq!(8, a);
assert_eq!(8, *b);
assert_eq!(8, *c);

Đặc trưng Deref

Triển khai Deref cho kiểu tùy chỉnh:

struct HộpĐựng<T>(T);

impl<T> HộpĐựng<T> {
    fn tạo(x: T) -> Self {
        HộpĐựng(x)
    }
}

use std::ops::Deref;
impl<T> Deref for HộpĐựng<T> {
    type Target = T;
    
    fn deref(&self) -> &T {
        &self.0
    }
}

let gốc = 7;
let bản_sao = HộpĐựng::tạo(gốc);
assert_eq!(7, *bản_sao);

Chuyển đổi Deref tự động

fn chào(tên: &str) {
    println!("Xin chào, {}!", tên);
}

let m = HộpĐựng::tạo(String::from("Rust"));
chào(&m);

Quy tắc chuyển đổi:

  • Từ &T sang &U khi T: Deref<Target=U>
  • Từ &mut T sang &mut U khi T: DerefMut<Target=U>
  • Từ &mut T sang &U khi T: Deref<Target=U>

Đặc trưng Drop

struct TàiNguyên {
    id: String,
}

impl Drop for TàiNguyên {
    fn drop(&mut self) {
        println!("Giải phóng tài nguyên {}", self.id);
    }
}

let t1 = TàiNguyên { id: "A".into() };
let t2 = TàiNguyên { id: "B".into() };
println!("Tài nguyên được tạo");

let t3 = TàiNguyên { id: "C".into() };
drop(t3);
println!("Tài nguyên C giải phóng trước");

Rc<T>

Con trỏ thông minh với bộ đếm tham chiếu:

enum DanhSách {
    MắtXích(i32, Rc<DanhSách>),
    KếtThúc,
}

use std::rc::Rc;
let gốc = Rc::new(DanhSách::MắtXích(5, 
    Rc::new(DanhSách::MắtXích(10, 
        Rc::new(DanhSách::KếtThúc)))));

let nhánh1 = DanhSách::MắtXích(3, Rc::clone(&gốc));
{
    let nhánh2 = DanhSách::MắtXích(4, Rc::clone(&gốc));
    println!("Số tham chiếu: {}", Rc::strong_count(&gốc));
}
println!("Số tham chiếu: {}", Rc::strong_count(&gốc));

Cell<T>

Thay đổi giá trị nội bộ tại thời điểm chạy:

use std::cell::Cell;
let ô = Cell::new(100);
let tham_chiếu1 = &ô;
let tham_chiếu2 = &ô;
tham_chiếu1.set(200);
println!("Giá trị: {}", ô.get());

RefCell<T>

Kiểm tra nguyên tắc mượn tại thời điểm chạy:

use std::cell::RefCell;
let ô = RefCell::new(50);

// Nhiều tham chiếu bất biến
let tham_chiếu1 = ô.borrow();
let tham_chiếu2 = ô.borrow();

// Một tham chiếu khả biến
let mut tham_chiếu_kb = ô.borrow_mut();
*tham_chiếu_kb += 10;

Thẻ: Rust Smart-Pointers Deref Drop Rc

Đăng vào ngày 17 tháng 6 lúc 05:34