Rust 如何在包装的HashMap上实现索引?

Rust 如何在包装的HashMap上实现索引?,rust,Rust,我想在HashMap类型上实现包装器类型的索引特性: use std::collections::HashMap; use std::option::Option; #[cfg(test)] use std::ops::Index; #[derive(Debug, Clone)] struct Value { val: i32, } #[derive(Debug, Clone)] pub struct HMShadow { hashmap: HashMap<Strin

我想在HashMap类型上实现包装器类型的索引特性:

use std::collections::HashMap;
use std::option::Option;

#[cfg(test)]
use std::ops::Index;

#[derive(Debug, Clone)]
struct Value {
    val: i32,
}

#[derive(Debug, Clone)]
pub struct HMShadow {
    hashmap: HashMap<String, Value>,
}

impl HMShadow {
    fn new() -> HMShadow {
        HMShadow {
            hashmap: {
                HashMap::<String, Value>::new()
            },
        }
    }

    fn insert<S>(&mut self, key: S, element: Value) -> Option<Value>
        where S: Into<String>
    {
        self.hashmap.insert(key.into(), element)
    }

    fn get(&mut self, key: &str) -> &mut Value {
        self.hashmap.get_mut(key).expect("no entry found for key")
    }
}

fn main()
{
    let mut s: HMShadow = HMShadow::new();
    let v: Value = Value { val : 5 };
    let _ = s.insert("test", v);
    println!("{:?}", s);
    println!("Get: {}", s.get("test").val);
}

#[cfg(test)]
impl<'a> Index<&'a str> for HMShadow {
    type Output = &'a mut Value;

    fn index(&self, key: &'a str) -> &&'a mut Value {
        match self.hashmap.get_mut(key) {
            Some(val) => &mut val,
            _ => panic!("no entry found for key"),
        }
    }
}

#[cfg(test)]
#[test]
fn test_index() {
    let mut s: HMShadow = HMShadow::new();
    let v: Value = Value { val : 5 };
    let _ = s.insert("test", v);
    println!("{:?}", s);
    println!("Index: {}", s["test"].val);
}
但是我不能做
fn索引(&'a self,key:&'a str)->&&'a mut值
,因为索引特征不允许
&'a self
,编译器错误:

错误[E0308]:方法与trait不兼容


由于你的问题很不清楚,我将重新解释如下:

我试图为我的结构实现
索引
,但不知何故,它不起作用

错误 查看编译器错误后,很明显,您的
索引的实现是错误的,原因有很多:

  • Index
    特性定义了一个名为
    Index
    的函数,该函数返回对该值的不可变引用。但是,您正在尝试返回一个可变引用。当然,Rust抱怨您正在实现的方法与特性不兼容
  • 您的
    索引
    实现的
    输出
    关联类型不应包装在引用中。因此,不是
    type Output=&'mut值您需要
    类型输出=值
  • 的生存期和
    索引
    函数中的输出是不相关的,但是您可以使用
    'a
    来实现这两个功能
  • 您需要将
    类型设置为公共,以便在trait实现中使用它
  • 代码
    索引
    的正确而简单的实现是:

    impl<'a> Index<&'a str> for HMShadow {
        type Output = Value;
    
        fn index(&self, key: &'a str) -> &Value {
            &self.hashmap[key]
        }
    }
    
    HMShadow的impl{ 类型输出=值; fn索引(&self,键:&'a str)->&Value{ &self.hashmap[key] } }
    由于您的问题很不清楚,我将重新解释如下:

    我试图为我的结构实现
    索引
    ,但不知何故,它不起作用

    错误 查看编译器错误后,很明显,您的
    索引的实现是错误的,原因有很多:

  • Index
    特性定义了一个名为
    Index
    的函数,该函数返回对该值的不可变引用。但是,您正在尝试返回一个可变引用。当然,Rust抱怨您正在实现的方法与特性不兼容
  • 您的
    索引
    实现的
    输出
    关联类型不应包装在引用中。因此,不是
    type Output=&'mut值您需要
    类型输出=值
  • 的生存期和
    索引
    函数中的输出是不相关的,但是您可以使用
    'a
    来实现这两个功能
  • 您需要将
    类型设置为公共,以便在trait实现中使用它
  • 代码
    索引
    的正确而简单的实现是:

    impl<'a> Index<&'a str> for HMShadow {
        type Output = Value;
    
        fn index(&self, key: &'a str) -> &Value {
            &self.hashmap[key]
        }
    }
    
    HMShadow的impl{ 类型输出=值; fn索引(&self,键:&'a str)->&Value{ &self.hashmap[key] } }
    我想,我在找

    #[cfg(test)]
    impl<'a> IndexMut<&'a str> for HMShadow {
        fn index_mut<'b>(&'b mut self, key: &'a str) -> &'b mut Value {
            self.hashmap.get_mut(key).expect("no entry found for key")
        }
    }
    
    #[cfg(测试)]
    HMShadow的impl{
    
    fn index_mut我想,我在寻找

    #[cfg(test)]
    impl<'a> IndexMut<&'a str> for HMShadow {
        fn index_mut<'b>(&'b mut self, key: &'a str) -> &'b mut Value {
            self.hashmap.get_mut(key).expect("no entry found for key")
        }
    }
    
    #[cfg(测试)]
    HMShadow的impl{
    
    fn index_mut
    Some(val)=>&mut val,
    这里,
    val
    是一个局部变量,所以我们不能返回它的引用。你能解释一下你想做什么吗?你完全不清楚你在问什么。你能重新表述你的问题吗?现在听起来像:“这个程序没有编译,请帮助”。你到底想实现什么?
    Some(val)=>&mut val,
    这里,
    val
    是一个局部变量,因此我们无法返回对它的引用。你能解释一下你想做什么吗?你问的问题完全不清楚。你能重新表述一下你的问题吗?现在听起来像:“此程序不可编译,请提供帮助”。您实际想要实现什么?您可能想看看
    Deref
    特性。如果您为包装器结构实现它,您可以免费获得
    HashMap
    中的所有方法。(您甚至可以获得用于索引的漂亮方括号语法)您可能想看看
    Deref
    特性。如果您为包装器结构实现它,您可以免费获得
    HashMap
    中的所有方法。(您甚至可以获得用于索引的漂亮方括号语法)