我正在学习Rust,并且为了练习,尝试实现Instrumented<T>
类型:
value
类型的T
字段; T
支持的所有基本操作,例如,相等,排序,算术; T
并计算调用次数; 这个想法借鉴了Alexander Stepanov的编程课程,在那里他用C ++实现了这个东西。使用Instrumented<T>
,可以使用Rust的特征系统,以非常通用的方式,在基本操作方面轻松测量T
类型上任何算法的复杂性。
首先,我正在尝试实施具有InstrumentedInt
特征的非通用Add
并计算additions
字段中的所有添加内容。完整代码:http://is.gd/AnF3Rf
这就是特质本身:
impl Add<InstrumentedInt, InstrumentedInt> for InstrumentedInt {
fn add(&self, rhs: &InstrumentedInt) -> InstrumentedInt {
self.additions += 1;
InstrumentedInt {value: self.value + rhs.value, additions: 0}
}
}
当然它不起作用,因为&self
是一个不可变的指针,并且其字段无法分配。
add
函数的参数是可变的,但编译器说它与特征定义不兼容。add
中声明impl InstrumentedInt
没有Add
特征,这不支持添加(没有鸭子输入)。这一切都可能吗?
P上。 S。之后,我要去:
additions
可变数组的指针替换uint
,以计算许多操作,而不仅仅是添加; InstrumentedInt
的所有实例之间共享此指针,可能只是在构造函数中提供参数,Instrumented<T>
; int
和f32
,Instrumented<int>
和Instrumented<f32>
应该有不同的计数器。也许这些对解决我当前的问题很重要。
谢谢!
答案 0 :(得分:2)
这正是various kinds of cells的用例。单元提供了实现内部可变性的工具,即&
引用后的可变性。例如,在您的情况下,InstrumentedInt
可能如下所示:
struct InstrumentedInt {
value: int,
additions: Cell<uint>
}
impl Add<InstrumentedInt, InstrumentedInt> for InstrumentedInt {
fn add(&self, rhs: &InstrumentedInt) -> InstrumentedInt {
self.additions.set(self.additions.get()+1);
InstrumentedInt {value: self.value + rhs.value, additions: Cell::new(0)}
}
}
至于你之后要做的事情,你可能很难实现它们。他们似乎有可能实施,但并不容易。例如,如果没有unsafe
,您将无法使用可变全局数据(可能使用Arc
和Mutex
等同步工具来使用不带unsafe
的全局变量,但我从来没有这样做,所以我现在不确定)。对于不同专业化的不同计数器,您可以再次使用AnyMap
或TypeMap
等库,使用某种全局变量。