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;