Rust 如何从HashMap或HashSet返回get_mut的结果?
我正在尝试包装一个Rust 如何从HashMap或HashSet返回get_mut的结果?,rust,borrow-checker,Rust,Borrow Checker,我正在尝试包装一个HashMap,如下定义,以从HashMap返回一个可变引用: 使用std:{collections::HashMap,marker::PhantomData}; 结构Id(usize,PhantomData); pub-struct-IdCollection(HashMap); impl Self::输出{ self.0.get_mut(id).unwrap() } } 以及由此产生的错误: 注意:首先,生命周期不能超过方法体上54:5定义的匿名生命周期#1。。。 -->s
HashMap
,如下定义,以从HashMap
返回一个可变引用:
使用std:{collections::HashMap,marker::PhantomData};
结构Id(usize,PhantomData);
pub-struct-IdCollection(HashMap);
impl Self::输出{
self.0.get_mut(id).unwrap()
}
}
以及由此产生的错误:
注意:首先,生命周期不能超过方法体上54:5定义的匿名生命周期#1。。。
-->src/id_容器。rs:54:5
|
54 |/fn索引(&mut self,id:&a id)->self::Output{
55 | | self.0.get_mut(id).unwrap()
56 | | }
| |_____^
注意:…这样引用就不会超过借用的内容
-->src/id_容器。rs:55:9
|
55 | self.0.get_mut(id).unwrap()
| ^^^^^^
注意:但是,生存期必须对impl上52:6定义的生存期“a”有效。。。
-->src/id_容器。rs:52:6
|
52 |为&'IdCollection导入迭代器{
类型项=(&'a Id,&'a T);
键入IntoIter=std::collections::hash_map::Iter IntoIterator for&'a mut IdCollection{
类型项=(&'a Id,&'a mut T T);
输入IntoIter=std::collections::hash_map::IterMut如果我正确理解了您试图实现的目标,那么我必须告诉您,它比您最初认为的要复杂一些
首先,您必须意识到,如果您喜欢使用HashMap
,那么键的类型需要是可散列和可比较的。因此Id
中的泛型类型参数T
必须绑定到这些特征,以使Id
可散列和可比较
您需要了解的第二件事是,处理索引操作符有两种不同的特性:不可变数据访问和可变数据访问
使用std::{
marker::PhantomData,
集合::HashMap,
cmp::{
情商,
PartialEq,
},
行动:{
指数
IndexMut,
},
哈希::哈希,
};
#[派生(PartialEq,散列)]
结构Id(usize、PhantomData)
其中T:PartialEq+Hash;
Id的impl Eq
其中T:PartialEq+Hash
{}
结构IdCollection(HashMap)
其中T:PartialEq+Hash;
IdCollection的impl索引
其中T:PartialEq+Hash
{
类型输出=T;
fn索引(&self,id:id)->&self::输出
{
self.0.get(&id).unwrap()
}
}
IdCollection的impl IndexMut
其中T:PartialEq+Hash
{
fn index_mut(&mut self,id:id)->&mut self::Output
{
self.0.get_mut(&id).unwrap()
}
}
fn main()
{
让muti=IdCollection(HashMap::new());
i、 0.插入(Id(12,PhantomData),99i32);
println!(“{:?}”,i[Id(12,幻影数据)];
i[Id(12,幻影数据)]=54i32;
println!(“{:?}”,i[Id(12,幻影数据)];
}
这似乎有点令人惊讶,但是IndexMut
的设计目的不是将元素插入集合,而是实际修改现有的元素。这就是HashMap
没有实现IndexMut
——这也是上面的示例使用HashMap::insert
方法进行ini的主要原因小心地放置数据。如您所见,稍后,当该值已经可用时,我们可以通过IdCollection::index_mut
在索引
之间修改它,而不是IndexMut
,加上错误的签名(我返回的是Self::Output
而不是&Self::Output
。。顺便说一句,T
不需要任何约束,因为我没有使用它(就像将它用作类型标记一样)。我将用我现在得到的代码编辑我的问题。谢谢:]当然,你可以为Id
提供你自己的哈希,只需使用usize
——但我不知道这是简化的伪代码还是实际实现,所以我冒昧地提供了最通用的解决方案。你提供的代码太好了,你有了问题的解决方案!你应该将其作为答案而不是问题的编辑发布,然后潜在地接受该答案。这样,问题在搜索结果中显示为已解决,人们可以对你的答案进行投票,你的解决方案对未来有相同问题的人更有帮助。