Rust 學習日記 #UnsafeCell
大家好,今天分享一個我自己實現的一個UnsafeCell,我也是最近剛開始認真學Rust,如果有什麼說錯了,請各位大佬指教。
use std::{fmt, mem};
use std::alloc::{alloc, handle_alloc_error, Layout};
struct SimpleUnsafeCell<T: fmt::Display> {
value: *mut T,
}
impl<T: fmt::Display> SimpleUnsafeCell<T> {
fn new(v: T) -> Self {
unsafe {
let layout = Layout::new::<T>();
let ptr = alloc(layout) as *mut T; // 申請T Size的內存
if ptr.is_null() { // 如果內存申請出現了有什麼問題,導致null pointer,交給handle_alloc_error處理
handle_alloc_error(layout);
}
ptr.write(v); // 把v的值寫入內存中。
Self { value: ptr } // 把value指針指向ptr所指的內存。
}
}
unsafe fn get_mut(&self) -> &mut T {
&mut *self.value
}
unsafe fn get_ref(&self) -> &T {
&*self.value
}
}
impl<T: fmt::Display> Drop for SimpleUnsafeCell<T> {
fn drop(&mut self) {
unsafe {
// 顯式調用T的釋構函數
std::ptr::drop_in_place(self.value);
// 然後再把申請來的內存釋放掉
std::alloc::dealloc(
self.value as *mut u8,
Layout::new::<T>()
);
}
}
}
impl<T: fmt::Display> fmt::Display for SimpleUnsafeCell<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", unsafe { self.get_mut() })
}
}
struct Point<T: fmt::Display> {
x: SimpleUnsafeCell<T>,
y: SimpleUnsafeCell<T>,
}
impl<T: fmt::Display> fmt::Display for Point<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {}", self.x, self.y)
}
}
fn main() {
let mut suc = SimpleUnsafeCell::new(String::from("Hello"));
unsafe {
let x = suc.get_ref();
println!("{}", *x);
let y = suc.get_mut();
y.push_str(", world!");
println!("{}", *x);
}
let point = Point { x: SimpleUnsafeCell::new(1), y: SimpleUnsafeCell::new(1) };
println!("{}", point);
}
推荐文章: