- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
use std::collections::HashMap;
use std::hash::Hash;
struct Watchable<'a, K, V, W: Watcher<'a, K, V>> {
data: HashMap<K, V>,
watchers: Vec<W>,
}
trait Watcher<'a, K, V> {
fn before_new(&mut self, key: &'a K, value: &'a V);
}
struct IndexWatcher<'a, I: 'a, V: 'a> {
data: HashMap<&'a I, &'a V>,
indexer: fn(&V) -> &I,
}
impl<'a, K, V, I> Watcher<'a, K, V> for IndexWatcher<'a, I, V>
where I: Eq + Hash
{
fn before_new(&mut self, key: &'a K, value: &'a V) {
let index = (self.indexer)(value);
self.data.insert(index, value);
}
}
error[E0392]: parameter `'a` is never used
--> src/main.rs:4:18
|
4 | struct Watchable<'a, K, V, W: Watcher<'a, K, V>> {
| ^^ unused type parameter
|
= help: consider removing `'a` or using a marker such as `std::marker::PhantomData`
有什么方法可以删除一些生命周期注释吗?似乎所有东西都有相同的生命周期a
。
起初,我没有输入任何具体的生命周期:
struct IndexWatcher<I, V> {
data: HashMap<&I, &V>,
indexer: fn(&V) -> &I,
}
编译器提示生命周期,所以我添加了它:
struct IndexWatcher<'a, I: 'a, V: 'a> {
data: HashMap<&'a I, &'a V>,
indexer: fn(&V) -> &I,
}
当我尝试实现没有生命周期的特征时:
trait Watcher<K, V> {
fn before_new(&mut self, key: &K, value: &V);
}
impl<'a, K, V, I> Watcher<K, V> for IndexWatcher<'a, I, V>
where I: Eq + Hash
{
fn before_new(&mut self, key: &K, value: &V) {
let index = (self.indexer)(value);
self.data.insert(index, value);
}
}
我得到了错误:
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> <anon>:18:33
|
18 | self.data.insert(index, value);
| ^^^^^
|
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> <anon>:17:21
|
17 | let index = (self.indexer)(value);
| ^^^^^^^^^^^^^^^^^^^^^
|
因此我的最终版本到处都是生命周期。
理想情况下,我想像下面这样在 Watchable
中使用 trait:
impl<K, V, W: Watcher<K, V>> Watchable<K, V, W>
where K: Eq + Hash {
fn insert(&mut self, k: K, v: V) -> Option<V> {
match self.data.entry(k) {
Occupied(mut occupied) => {
{
let k = occupied.key();
let old = occupied.get();
for watcher in &mut self.watchers {
watcher.before_change(k, &v, old);
}
}
let old = occupied.insert(v);
Some(old)
},
Vacant(vacant) => {
{
let k = vacant.key();
for watcher in &mut self.watchers {
watcher.before_new(k, &v);
}
}
vacant.insert(v);
None
}
}
}
}
trait Watcher<K, V> {
fn before_new(&mut self, key: &K, value: &V);
fn before_change(&mut self, key: &K, value: &V, old: &V);
}
最佳答案
您可以使用 higher-rank trait bound 来消除错误而不是生命周期参数:
struct Watchable<K, V, W: for<'a> Watcher<'a, K, V>> {
data: HashMap<K, V>,
watchers: Vec<W>,
}
但这并不能解决您的问题。 IndexWatcher
不会满足边界 for<'a> Watcher<'a, K, V>
因为 IndexWatcher<'a, I, V>
只实现 Watcher<'a, K, V>
对于一个特定的生命周期,而不是所有可能的生命周期。
从根本上说,问题在于 you're trying to put a value and a reference to that value in the same struct (间接地)。也就是说,您的想法是希望观察者从 Watchable
中借用数据。 ,但是 Watchable
还拥有观察者。请抓紧时间read this question以及 Shepmaster 的回答,以了解为什么这个想法行不通。
特别注意,在 Watchable
中插入条目或从中删除条目的 HashMap
由于 HashMap
,可能会使任何观察者中的引用无效需要重新分配存储,这可能会导致键和值的地址发生变化。
我会做的是将键和值包装在 Rc
中(或者 Arc
如果你想跨线程共享 Watchable
)。从 Rc<V>
中获取共享索引值虽然可能有问题。考虑将索引函数更改为 fn(&V) -> I
,并让索引函数返回克隆(如果克隆索引值太昂贵,它们可以是 Rc
的克隆)或句柄。
关于rust - 将泛型类型绑定(bind)到需要生命周期的特征时未使用的类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43684768/
我正在开发一个使用多个 turtle 的滚动游戏。玩家 turtle 根据按键命令在 Y 轴上移动。当危害和好处在 X 轴上移动时,然后循环并改变 Y 轴位置。我尝试定义一个名为 colliding(
我不明白为什么他们不接受这个作为解决方案,他们说这是一个错误的答案:- #include int main(void) { int val=0; printf("Input:- \n
我正在使用基于表单的身份验证。 我有一个注销链接,如下所示: 以及对应的注销方法: public String logout() { FacesContext.getCurren
在 IIS7 应用程序池中有一个设置 Idle-time out 默认是 20 分钟,其中说: Amount of time(in minutes) a worker process will rem
我是一名优秀的程序员,十分优秀!