【发布时间】:2017-09-15 09:14:06
【问题描述】:
我想为 Map 创建一个具有以下定义的特征:
pub trait Map<K: Sync, V> {
fn put(&mut self, k: K, v: V) -> Option<V>;
fn upsert<U: Fn(&mut V)>(&self, key: K, value: V, updater: &U);
fn get<Q: ?Sized>(&self, k: &Q) -> Option<V> where K: Borrow<Q>, Q: Eq + Hash + Sync;
// other methods ommited for brevity
}
现在,问题是如果我实现这个特性,例如 MyHashMap,那么我不能有这样的表达式:
let map: Box<Map<i32, i32>> = Box::new(MyHashMap::<i32, i32>::new());
错误是:
特征
map::Map不能成为对象
如何解决这个问题?因为直接开始使用 Map 实现并不是一个好主意,因为这不是一个好的软件工程实践。
主要问题是 trait 中的 get 和 upsert 方法接受泛型类型参数。我的第一次尝试是摆脱这些泛型类型参数。
对于 get 方法,它是可能的,尽管它偏离了 get 在 rust 集合中的常见签名,并使其使用场景更加有限。结果如下:
pub trait Map<K: Sync, V> {
fn put(&mut self, k: K, v: V) -> Option<V>;
fn upsert<U: Fn(&mut V)>(&self, key: K, value: V, updater: &U);
fn get(&self, k: &K) -> Option<V>;
// other methods ommited for brevity
}
但是,我不知道如何删除 upsert 中的泛型类型参数。
你知道如何处理这个问题吗?
【问题讨论】:
-
因为直接开始使用 Map 实现不是一个好主意,因为它不是一个好的软件工程实践。 => 你需要更新你的工程实践。在 Rust 或 C++ 等原生语言中,使用具体实例(和泛型)而不是接口可以让编译器挤出最后一点性能。