【问题标题】:Unconstrained lifetime error when implementing Index trait实现索引特征时不受约束的生命周期错误
【发布时间】:2016-12-23 00:53:15
【问题描述】:

我有一个拥有HashMap<String, String> 的结构,

struct Test {
    data: HashMap<String, String>,
}

我正在尝试为这种类型实现 Index 特征以映射到 hashmap 的 Index 实现(涉及其他逻辑,因此我无法公开 hashmap)。

如果我只是获得对哈希图中值的引用,则此方法有效:

impl<'b> Index<&'b str> for Test {
    type Output = String;
    fn index(&self, k: &'b str) -> &String {
        self.data.get(k).unwrap()
    }
}

但是,我想从中获得&amp;Option&lt;&amp;String&gt;,例如data.get()。所以我尝试了这个:

impl<'b, 'a> Index<&'b str> for Test {
    type Output = Option<&'a String>;
    fn index(&'a self, k: &'b str) -> &Option<&'a String> {
        &self.data.get(k)
    }
}

这会导致:

error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
 --> <anon>:8:10
  |
8 | impl<'b, 'a> Index<&'b str> for Test {
  |          ^^ unconstrained lifetime parameter

我理解“'a 中的unconstrained lifetime parameter”。现在'aTest 本身的生命周期,所以我想要(我认为)where 'Self: 'a(所以self 的寿命至少与'a 一样长)。我似乎无法为Index impl 解决这个问题?我尝试将PhantomData 添加到我的Test 中。但我没有得到任何地方。有什么建议么?

【问题讨论】:

  • 你正在尝试的东西是不可能的。 index() 将始终返回一个引用,并且您不能返回对函数本地 Option&lt;T&gt; 的引用,因为它的寿命不够长。除此之外,我认为(只是一个疯狂的猜测)生命周期问题实际上与流迭代器相同。如果是这样的话,Rust 的类型系统还不足以表达这一点。但无论如何,您不想通过index() 返回Option&lt;T&gt;,因为它预计会在无效索引上出现恐慌。只需编写一个get() 方法,就像hashmap 一样。我希望这可能会有所帮助。
  • 是的,我相信你是对的。从语义上讲,Index 应该恐慌,所以get() 是更好的选择。

标签: rust


【解决方案1】:

正如 cmets 中所指出的,您无法完全按照自己的意愿行事。但是,看起来您真正想要的是复制HashMapget 方法。所以我建议要么自己写,要么实现Deref(和 DerefMut)让结构的所有者不可变直接访问内部HashMap。希望这意味着用户不能搞乱你的结构的内部逻辑。请记住,如果您同时执行这两种操作,则 Deref 将不会被称为 HashMap::get,因为 Test::get 将可用。

struct FooMap {
    data: HashMap<String, String>
}

复制get

impl FooMap {
    pub fn get(&self, index: &str) -> Option<&String> { self.data.get(index) }
}

使用Deref:

impl Deref for FooMap {
    type Target = HashMap<String, String>;
    fn deref(&self) -> &Self::Target { &self.data }
}

Example code on Rust Playground

【讨论】:

  • 逻辑有点复杂,所以在某些情况下查找实际上可能不是在哈希上;无论如何,这就是我正在使用的 - 它不必编写样板来将查找映射到内部容器。
猜你喜欢
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 2018-03-19
  • 2021-05-24
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 2022-10-23
相关资源
最近更新 更多