我想学习如何将Index
特性用于我的玩具roguelike但是甚至无法让它在一个无用的虚拟场景中工作。
use std::ops::Index;
// Dummy struct that wraps i32
#[derive(Clone, Copy, Debug)]
pub struct Integer {
pub val: i32,
}
impl Integer {
fn new(num: i32) -> Self {
Integer { val: num }
}
}
// Using the index operator on an Integer should add the index to the Integer's value.
// let i = Integer::new(20);
// i[20];
// The above code should make it so i.val == 40
impl Index<Integer> for Integer {
type Output = i32;
// The error is in the following line:
fn index(&self, to_add: Integer) -> &Self::Output {
self.val + to_add.val;
}
}
// The code causes an error before it reaches this
fn main() {
let mut i = Integer::new(20);
let mut n = Integer::new(30);
println!("i[20] is: {:?}", i[n]);
}
我收到此错误:
error[E0308]: mismatched types
--> src/main.rs:23:55
|
23 | fn index(&self, to_add: Integer) -> &Self::Output {
| _______________________________________________________^
24 | | self.val + to_add.val;
25 | | }
| |_____^ expected &i32, found ()
|
= note: expected type `&i32`
found type `()`
我真的不知道我在说什么,但我想这个价值在它到达函数结尾之前就已经消失了?我还没有完全理解一生。
我知道这看起来像是“没有想到我会做什么修复”的问题,但我很想知道我在这里做错了什么,所以我可以从中学习。
答案 0 :(得分:1)
编者注:在OP彻底改变之前,这个答案适用于原始问题。它不再适用于发布的问题。
Index
documentation说,强调我的:
Index
特征用于指定在不可变上下文中使用的container[index]
等索引操作的功能。
您正在尝试 mutate 该值,这根本不可能。您也可以通过index
:
pub trait Index<Idx>
where
Idx: ?Sized,
{
type Output: ?Sized;
fn index(&self, index: Idx) -> &Self::Output;
}
这里任何地方都没有mut
;你不能实现&#34;具有完全不同签名的特征!您也无法更改其中一个参数的类型(在本例中为self
)。
直截了当地说,Index
是要使用的错误的特征。此外,如果您以这种方式实现代码,那么惯用的Rust用户将真的不高兴;我们通常不会重复使用运营商以获得完全不同的含义。人群。
相反,这应该只是一个名称为
的函数impl Integer {
fn increment(&mut self, to_add: i32) {
self.val += to_add;
}
}
或者,您可以实施DerefMut
:
use std::ops::{Deref, DerefMut};
impl Deref for Integer {
type Target = i32;
fn deref(&self) -> &Self::Target { &self.val }
}
impl DerefMut for Integer {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.val }
}
然后像
一样使用它let mut i = Integer::new(20);
*i += 20;
println!("i[20] is: {:?}", i);