首页 > 解决方案 > 为具有生命周期的类型实现 Borrow trait

问题描述

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

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

我有一个HashMap<Key, _>, 并且我想通过对键类型的引用来查找值(即不必拥有该字符串)。看来我需要做的是:

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

(实际上我想要KeyRef<'a>(&'a str),但使用String可以作为一个更清晰的例子)

  1. 实施Borrow<KeyRef<'_>> for Key

我已经尽力了,这是一个游乐场链接

我最明确的尝试(注释所有生命周期)是:

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与特征声明不匹配”。

直觉上感觉这应该是可能的:

但是编译器似乎不喜欢我明确尝试证明 (with where 'b: 'a),并且将其关闭我得到“由于要求冲突,无法推断借用表达式的适当生命周期”

标签: rustlifetimeborrow

解决方案


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

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

推荐阅读