我想在HashMap类型上为包装类型实现Index trait:
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);
}
执行rustc --test tt.rs
编译器说:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements --> tt.rs:51:28 | 51 | match self.hashmap.get_mut(key) { | ^^^^^^^ | help: consider using an explicit lifetime parameter as shown: fn index(&'a self, key: &'a str) -> &&'a mut Value --> tt.rs:50:5 | 50 | fn index(&self, key: &'a str) -> &&'a mut Value { | ^
但是我不能fn index(&'a self, key: &'a str) -> &&'a mut Value
因为索引特征不允许&'a self
和编译器错误:
错误[E0308]:与特征不兼容的方法
答案 0 :(得分:5)
由于你的问题很不清楚,我将重新解释如下:
我正在尝试为我的结构实现
Index
,但不知何故它不起作用。
在查看编译器错误后,很明显您的Index
实现有多种原因是错误的:
Index
特征定义了一个名为index
的函数,该函数返回对该值的不可变引用。但是,您尝试返回可变引用。当然,Rust抱怨你实现的方法与特征不兼容。Output
实现的Index
关联类型不应包含在引用中。因此,您需要type Output = &'a mut Value;
type Output = Value;
key
的生命周期和index
函数中的输出不相关,但您同时使用'a
。Value
类型设为公开,才能在特征实施中使用它。 Index
的正确而简单的实现是:
impl<'a> Index<&'a str> for HMShadow {
type Output = Value;
fn index(&self, key: &'a str) -> &Value {
&self.hashmap[key]
}
}
答案 1 :(得分:2)
我猜,我在寻找
#[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")
}
}