rust - 为具有生存期的类型实现借阅特征

标签 rust lifetime borrow

我正在尝试使用。在程序中使用强类型包装器来包装“键”,这样我就不会将任意字符串误认为是键。我有:

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Key(String);
我有一个HashMap<Key, _>,我想通过引用键类型来查找值(即不必拥有字符串)。看来我需要做的是:
  • 为我的 key 创建一个“ref”类型:

  • #[derive(Debug, Clone, PartialEq, Eq, Hash)]
    struct KeyRef<'a>(&'a String);
    
    (实际上,我想要KeyRef<'a>(&'a str),但是使用String可以使示例更清晰)
  • 实现Borrow<KeyRef<'_>> for Key

  • 我已经尽力了,这是playground link
    我最明确的尝试(注释所有生命)是:
    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
        }
    }
    
    这给了我一个错误:“方法borrow上的生命周期参数或界限与特征声明不匹配”。
    凭直觉,这应该是可能的:
  • KeyRef拥有生存期'a的引用,因此KeyRef的任何值都不能超过'a
  • fn borrow<'b>(&'b self)中,由于上述
  • 'b不能大于'a
    但是编译器似乎不喜欢我的显式尝试(使用where 'b: 'a)来证明这一点,而将其取消后,由于“需求冲突,我无法推断出借用表达式的适当生存期”

    最佳答案

    据我了解您的情况,您不必要地使事情复杂化。一个简单的实现:

    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"));
    }
    

    关于rust - 为具有生存期的类型实现借阅特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65858144/

    相关文章:

    arrays - Rust 的数组边界检查会影响性能吗?

    python - Dnspython:设置查询超时/生命周期

    使用rust 错误 : borrow occurs after drop a mutable borrow

    rust - 有没有办法同时以不可变和可变的方式借用 RefCell?

    web - 如何在 actix-web 中定义 URL 参数?

    rust - Iterator filter() 双重引用借用错误

    rust - 当返回使用 StdinLock 的结果时,为什么保留对 stdin 的借用?

    rust - Actix Web 的终身问题

    rust - 如何在迭代器中使用字符串而不是 &str,if/else block