先用一小段代码辅助说明结论(涉及多线程、多个可变引用下的实现)
use std::sync::Arc;
use std::sync::Mutex;
struct Point {
pub x: u32,
pub y: u32
}
impl Point {
pub fn get_instance() -> Arc<Mutex<Point>> {
static mut POINT: Option<Arc<Mutex<Point>>> = None;
unsafe {// Rust中使用可变静态变量都是unsafe的
POINT.get_or_insert_with(|| {
// 初始化单例对象的代码
Arc::new(Mutex::new(Point {x: 0, y: 0}))
}).clone()
}
}
}
Option<...>作为静态变量来存储单例对象的原始全局指针,用get_or_insert_with方法来初始化单例对象Arc<Mutex<T>> 或者Arc<RwLock<T>>来持有单例对象;如果不需要单例对象的可变引用,直接用Arc<T>即可;如果是单线程程序,Arc可以可用Rc替代Box表示唯一的指针引用,不能clone。单例对象是要被多处代码所引用的,Box<T>只能move不能clone,所以根本无法实现将一个Box<T>作为共享指针。
如果不需要可变引用,那就没有必要使用Mutex或者RwLock了。可以返回一个Arc<T>或者&‘static T
pub fn get_instance() -> Arc<Point> {
static mut POINT: Option<Arc<Point>> = None;
unsafe {// Rust中使用可变静态变量都是unsafe的
POINT.get_or_insert_with(|| {
// 初始化单例对象的代码
Arc::new(Point {x: 0, y: 0})
}).clone()
}
}
// 返回&'static Point
pub fn get_instance() -> &'staic Point {
static mut POINT: Option<Arc<Point>> = None;
unsafe {// Rust中使用可变静态变量都是unsafe的
POINT.get_or_insert_with(|| {
// 初始化单例对象的代码
Arc::new(Point {x: 0, y: 0})
});
POINT.as_ref().unwrap()
}
}原文:https://www.cnblogs.com/metaworm/p/11969270.html