简体   繁体   English

为具有生命周期的类型实现 Borrow trait

[英]Implementing Borrow trait for a type with a lifetime

I'm trying to use.我正在尝试使用。 strongly typed wrapper for a "keys" in my program, so that I don't mistake arbitrary strings for a Key.我的程序中的“键”的强类型包装器,这样我就不会将任意字符串误认为是键。 I have:我有:

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Key(String);

I have a HashMap<Key, _> , and I want to lookup values with a reference to a key type (ie not having to own the string).我有一个HashMap<Key, _> ,我想通过引用键类型来查找值(即不必拥有字符串)。 It seems like what I need to do is:看来我需要做的是:

  1. create a "ref" type for my Key:为我的密钥创建一个“ref”类型:
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct KeyRef<'a>(&'a String);

(in reality I'd want KeyRef<'a>(&'a str) , but using String makes for a clearer example) (实际上我想要KeyRef<'a>(&'a str) ,但使用String可以提供更清晰的示例)

  1. implement Borrow<KeyRef<'_>> for Key Borrow<KeyRef<'_>> for Key

I've tried my best, here's a playground link我已经尽力了,这是一个游乐场链接

My most explicit attempt (annotating all lifetimes) is:我最明确的尝试(注释所有生命周期)是:

impl<'a> Borrow<KeyRef<'a>> for Key {
    fn borrow<'b>(&'b self) -> &'b KeyRef<'a> where 'b: 'a {
        let string_ref : &'a String = &self.0;
        let key_ref : &'a KeyRef<'a> = &KeyRef(string_ref);
        key_ref
    }
}

Which gives me the error: "lifetime parameters or bounds on method borrow do not match the trait declaration".这给了我错误:“方法borrow的生命周期参数或边界与特征声明不匹配”。

Intuitively it feels like this should be possible:直觉上感觉这应该是可能的:

  • KeyRef holds a reference of lifetime 'a , so any value of KeyRef cannot outlive 'a . KeyRef 持有生命周期'a的引用,因此 KeyRef 的任何值都不能超过'a
  • In fn borrow<'b>(&'b self) , 'b can't be greater than 'a due to the abovefn borrow<'b>(&'b self)中,由于上述原因, 'b不能大于'a

But the compiler doesn't seem to like my explicit attempt to demonstrate that (with where 'b: 'a ), and leaving it off I get "cannot infer an appropriate lifetime for borrow expression due to conflicting requirements"但是编译器似乎不喜欢我明确尝试证明这一点(使用where 'b: 'a ),并且将其关闭我得到“由于要求冲突,无法推断借用表达式的适当生命周期”

As far as I understand your situation, you are needlessly overcomplicating things.据我了解你的情况,你不必要地把事情复杂化了。 A straightforward implementation:一个简单的实现:

use std::collections::HashMap;
use std::borrow::Borrow;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Key(String);

impl Borrow<str> for Key {
    fn borrow(&self) -> &str {
        &self.0
    }
}

impl Borrow<String> for Key {
    fn borrow(&self) -> &String {
        &self.0
    }
}

fn main() {
    let mut map = HashMap::new();
    map.insert(Key("one".to_owned()), 1);

    // Because Key is Borrow<String>
    println!("{:?}", map.get("one".to_owned()));
    
    // Because Key is Borrow<str>
    println!("{:?}", map.get("one"));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM