语境
我有一个DataStore<Key,Value>
特征可以抽象出数据存储。(例如,我可以为包装Vecs
和HashMaps
. (编辑self
:在特征定义中添加了引用,如下。)
// Stores data of type V indexed by K
trait DataStore<K, V> {
fn new() -> Self;
fn get(&self, k: K) -> Option<&V>;
fn insert(&mut self, v: V) -> Option<K>;
}
我现在想定义一个Thing
包含两个数据存储的结构:一种类型Apple<T>
的存储, 和另一种类型的存储,Banana<T>
。这是我的第一次尝试,
// some objects I'd like to keep in DataStores
struct Apple<T> { shine: T }
struct Banana<T> { spottedness: T }
// Attempt #1: cumbersome, have to always specify generic constraints when
// using Thing elsewhere
pub struct Thing<K, T, AppleStore, BananaStore>
where AppleStore: DataStore<K, Apple<T>>,
BananaStore: DataStore<K, Banana<T>>
{
apple_store: AppleStore,
banana_store: BananaStore,
}
这种方法使用起来很麻烦,因为<K, T, AppleStore, BananaStore> where ...
每当我想传递Thing
给一个函数或实现一个特征时,我必须总是输入,Thing
即使所述函数或特征不关心这两个商店中的任何一个。例如,如果我想实现一个特征,它对Thing
其他类型的属性执行一些不相关的操作,T
我仍然必须告诉它关于K
,AppleStore
和BananaStore
.
我了解了类型别名并尝试了以下方法:
// Attempt #2: looks easier to use. only two generics on Thing: the type of
// the indexes and the type of the internal parameters. not sure
// about the role of dyn, though, since this should be checkable
// at compile time
type AppleStore<K, T> = dyn DataStore<K, Apple<T>>;
type BananaStore<K, T> = dyn DataStore<K, Banana<T>>;
pub struct Thing<K, T> {
apple_store: AppleStore<K, T>,
banana_store: BananaStore<K, T>,
}
当我尝试BananaStore
在Thing
的构造函数中创建一个新的时,出现了一个新问题。这在尝试 #1 中是允许的,因为特征允许实现 (1) 不&self
作为参数和 (2) 返回类型的函数Self
。但这在尝试 #2 中是不允许的,因为动态特征需要事物是Size
d 并且返回是不允许的Self
。(或者其他的东西?)
impl<K, T> Thing<K, T> {
pub fn new(apple_store: AppleStore<K, T>) {
Thing {
apple_store: apple_store,
banana_store: BananaStore::new() // not allowed to do this with
// dynamic type aliases?
}
}
问题
我是否需要创建一个BananaStore
外部Thing
并将其作为参数传递,或者有没有办法BananaStore
从外部隐藏构造?ThingBuilder
如果我的目标之一是隐藏不必要的(可选)对象创建,我想类似 a的方法可能是一种有效的方法。但我也不想提供一个默认的实现者:用户应该明确声明使用BananaStore
哪种类型。DataStore
BananaStore
我以这种方式提出问题,因为最终我希望Thing
'在多个实例AppleStore
之间实际共享;Thing
也就是说,多个可以在商店Things
中引用相同的内容。Apple<T>
但每个Thing
人都会有自己的BananaStore
。我知道这需要使用Rc
orArc
或类似的东西,AppleStore
但是当我到达它时我会越过那座桥。