我试图设计一对特征(例如来自线性代数的 RowVector
和 ColumnVector
),其中每个特征从其中一个方法返回另一个特征(例如 transpose
) . 我希望将来能够添加任何特征的实现(例如密集和稀疏矢量实现) .
#[macro_use]
extern crate derive_new;
trait RowVector<Element> {
fn transpose(self) -> ColumnVector<Element>;
}
trait ColumnVector<Element> {
fn transpose(self) -> RowVector<Element>;
}
#[derive(new, Debug)]
struct VecRowVector<Element> {
vec: Vec<Element>
}
#[derive(new, Debug)]
struct VecColumnVector<Element> {
vec: Vec<Element>
}
impl<Element> RowVector<Element> for VecRowVector<Element> {
fn transpose(self) -> VecColumnVector<Element> {
VecColumnVector::new(self.vec)
}
}
impl<Element> ColumnVector<Element> for VecColumnVector<Element> {
fn transpose(self) -> VecRowVector<Element> {
VecRowVector::new(self.vec)
}
}
fn main() {
let row_vector = VecRowVector::new(vec![1,2,3]);
let col_vector = VecColumnVector::new(vec![1,2,3]);
println!("{:?}", row_vector.transpose());
println!("{:?}", col_vector.transpose());
}
我得到一个错误,说 VecColumnVector
不是 ColumnVector
,它期望 'static
值 .
error[E0053]: method `transpose` has an incompatible type for trait
--> src\main.rs:22:31
|
4 | fn transpose(self) -> ColumnVector<Element>;
| --------------------- type in trait
...
22 | fn transpose(self) -> VecColumnVector<Element> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected trait ColumnVector, found struct `VecColumnVector`
|
= note: expected type `fn(VecRowVector<Element>) -> ColumnVector<Element> + 'static`
= note: found type `fn(VecRowVector<Element>) -> VecColumnVector<Element>`
我没有 VecColumnVector
ColumnVector
的子类型?或者我是否需要告诉特性它不需要是 static
生命周期?
2 回答
你正试图回归一个特质 . 虽然这可以使用trait object,但它可能不是你想要做的 . 更好的设计是引入一个
Transpose
特征,你可以用与Rust的内置From
和Into
转换特征类似的方式建模 .当需要关联两种类型时,最佳解决方案通常是associated types . 这排除了使用像特征对象一样的动态调度,但在Rust中动态调度仍然非常有限 . 使用静态调度时,Rust更具表现力,相关类型具有杠杆作用 .