如何解决如何为本身不存储值的类型实现IndexMut
我有一个结构,我们称其为A
和一个枚举E
。
#[derive(Debug,Clone,Copy,PartialEq,Eq)]
enum E {
Val1,Val2,Val3,Val4,}
#[derive(Debug,Eq)]
struct A {
a: u64,b: u64,}
我将Index
特质实现为:
impl Index<usize> for A {
type Output = E;
fn index(&self,index: usize) -> &Self::Output {
match ((self.a >> index) & 1,(self.b >> index) & 1) {
(0,0) => &E::Val1,(0,1) => &E::Val2,(1,0) => &E::Val3,1) => &E::Val4,_ => unreachable!(),}
}
}
我在set_val
上有一个方法A
。
impl A {
pub fn set_val(&mut self,idx: usize,val: E) {
match val {
E::Val1 => {
self.a &= !1 << idx;
self.b &= !1 << idx;
}
E::Val2 => {
self.a &= !1 << idx;
self.b |= 1 << idx;
}
E::Val3 => {
self.a |= 1 << idx;
self.b &= !1 << idx;
}
E::Val4 => {
self.a |= 1 << idx;
self.b |= 1 << idx;
}
}
}
}
我想知道如何使用set_val
来实现IndexMut
,以便可以做到:
let mut a = A {a: 0,b: 0};
a[4] = E::Val3;
// instead of
a.set_val(4,E::Val3);
解决方法
正如@rodrigo在评论中指出的那样,IndexMut
返回一个可变的引用。这样,您可以执行&mut slice[index]
之类的操作来获取给定索引处元素的可变引用,该索引已存在于内存中。
但是,您将在此处创建并返回E
的实例。写入该值不会更新原始的a
和b
变量。这是因为一旦您从index_mut
返回,就无法再访问self
,并且无法更新任何变量;调用者应该简单地写回您返回的可变引用,在这种情况下,它什么也不做。
正如@eggyal指出的那样,建议的IndexSet
trait可能会实现,它看起来像这样(我的想法基于this postponed PR):
trait IndexSet<Index,Rhs> {
/// `self[index] = rhs`
fn index_set(&mut self,index: Index,rhs: Rhs);
}
然后,您可以像实现set_val
方法那样完全实现它:
impl IndexSet<usize,E> for A {
pub fn index_set(&mut self,idx: usize,val: E) {
match val {
E::Val1 => {
self.a &= !1 << idx;
self.b &= !1 << idx;
}
E::Val2 => {
self.a &= !1 << idx;
self.b |= 1 << idx;
}
E::Val3 => {
self.a |= 1 << idx;
self.b &= !1 << idx;
}
E::Val4 => {
self.a |= 1 << idx;
self.b |= 1 << idx;
}
}
}
}
手指对此功能表示怀疑。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。