Rust 笔记 - 实现unique pointer

455 阅读1分钟

Unique 封装了一个裸指针的步骤:

  • 对 T 可变
  • 拥有类型 T 的值,用于 drop 检查
  • 如果 T 是 Send/Sync,那就也是 Send/Sync
  • 指针永远不为 null,使用Option做空指针优

下面是实例代码:

use std::marker::PhantomData;

struct Unique<T> {
    ptr: *const T,           // 使用*const保证变性
    _marker: PhantomData<T>, // 用于drop检查
}

unsafe impl<T: Send> Send for Unique<T> {}
unsafe impl<T: Sync> Sync for Unique<T> {}

impl<T> Unique<T> {
    pub fn new(ptr: *mut T) -> Self {
        Unique {
            ptr: ptr,
            _marker: PhantomData,
        }
    }

    pub fn as_ptr(&self) -> Option<*const T> {
        if std::ptr::null::<T>() == self.ptr {
            return None;
        }
        Some(self.ptr as *const T)
    }

    pub fn as_mut_ptr(&self) -> Option<*mut T> {
        if std::ptr::null::<T>() == self.ptr {
            return None;
        }
        Some(self.ptr as *mut T)
    }

    pub fn as_ref(&self) -> Option<&T> {
        if std::ptr::null::<T>() == self.ptr {
            return None;
        }
        unsafe {
            Some(&*self.ptr as &T)
        }
    }

    pub fn as_mut_ref(&self) -> Option<&mut T> {
        if std::ptr::null::<T>() == self.ptr {
            return None;
        }
        unsafe {
            let ptr = self.ptr as *mut T;
            Some(&mut *ptr)
        }
    }
}

fn main() {
    let mut s = String::from("hello world");
    let u = Unique::new(&mut s);

    if let Some(ptr) = u.as_ptr() {
        unsafe {
            println!("{}", *ptr);
        }
    }

    if let Some(ptr) = u.as_mut_ptr() {
        unsafe {
            println!("{}", *ptr);
        }
    }

    if let Some(ptr) = u.as_ref() {
        println!("{}", ptr);
    }

    if let Some(ptr) = u.as_mut_ref() {
        *ptr = ptr.to_owned() + " good";
        println!("{}", s);
    }
}