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);
}
}