我有以下的定义:
struct MyCustomFactory;
trait Factory {
fn new<'a>(entity: &'a str) -> Arc<dyn Display + 'a>
where
Self: Sized;
}
impl Factory for MyCustomFactory {
fn new<'a>(entity: &'a str) -> Arc<dyn Display + 'a>
where
Self: Sized,
{
Arc::new(entity)
}
}
更高层次的问题:
我试图创建一个全局静态(不可变)字符串到实现Factory
trait的结构体的映射表。目标是,对于地图中的任何值成员,我可以像处理Factory
一样对待它,调用new
,然后会得到某些东西,这个东西(在本例中)实现了Display
trait。
我有以下内容:
static ITEMS: Lazy<BTreeMap<&'static str, Arc<dyn Factory>>> =
Lazy::new(|| {
let mut map = BTreeMap::new();
let value = Arc::new(MyCustomFactory) as Arc<dyn Factory>;
map.insert("foo", value);
map
});
编译器报错如下:
77 | / static ITEMS: Lazy<BTreeMap<&'static str, Arc<dyn Factory>>> =
78 | | Lazy::new(|| {
79 | | let map = BTreeMap::new();
80 | | let value = Arc::new(MyCustomFactory) as Arc<dyn Factory>;
... |
88 | | });
| |_______^ `(dyn Factory + 'static)` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `(dyn Factory + 'static)`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<(dyn Factory + 'static)>`
= note: required because of the requirements on the impl of `std::marker::Send` for `alloc::collections::btree::node::Root<&'static str, std::sync::Arc<(dyn Factory + 'static)>>`
= note: required because it appears within the type `std::collections::BTreeMap<&'static str, std::sync::Arc<(dyn Factory + 'static)>>`
= note: required because of the requirements on the impl of `std::marker::Sync` for `once_cell::imp::OnceCell<std::collections::BTreeMap<&'static str, std::sync::Arc<(dyn Factory + 'static)>>>`
= note: required because it appears within the type `once_cell::sync::OnceCell<std::collections::BTreeMap<&'static str, std::sync::Arc<(dyn Factory + 'static)>>>`
= note: required because of the requirements on the impl of `std::marker::Sync` for `once_cell::sync::Lazy<std::collections::BTreeMap<&'static str, std::sync::Arc<(dyn Factory + 'static)>>>`
= note: shared static variables must have a type that implements `Sync`
我尝试过的方法:
Implement
Sync
against the trait: Declaring the trait to havetrait Factory : Sync
, (meaning all items which implement the trait, must implementSync
) and/or defining:| 66 | unsafe impl Sync for dyn Factory {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
Wrapping
Arc<dyn Factory>
: I've tried usingMutex
/RefCell
/OnceCell
and others, all resulting in the same error. It seems like there should be a way to treat the underlyingMyCustomFactory
as a Singleton that can be locked around. It's fine (and expected) that's there's only once instance of this struct globally.