我想设计一对性状(例如线性代数中的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
?
如何更新'RowVector'和'ColumnVector'特性以表示每个实现它们的结构必须也实现相应的'Transpose'? – drhagen
我认为这会变得非常复杂:每个特征的约束之间会有循环引用,因为您必须以严格的对定义impls,这很难在Rust中表达。一个更简单(也更灵活)的设计是不对这些类型本身施加任何约束,而是对使用类型的地方施加约束。 –
所以我不能编写像'f(r:&RowVector ,c:&ColumnVector )'这样的函数,并期望能够在体内使用'transpose'?我必须列出'Transpose'以及我将需要的其他线性代数运算? –
drhagen