我在Rust中有一个矩阵数据类型,它支持通用元素数据类型。
pub struct Matrix<T> {
data: Vec<T>, // row-major storage
nrows: usize,
ncols: usize,
}
我想创建一系列不同的矩阵构造函数,例如zero
和eye
,它们分别输出零矩阵和单位矩阵。标准的Matrix::new()
构造函数很简单:
impl<T> Matrix<T> {
pub fn new(data: Vec<T>, nrows: usize, ncols: usize) -> Matrix<T> {
assert!(data.len() == nrows*ncols);
Matrix { data: data, nrows: nrows, ncols: ncols }
}
}
基础类型T
是从初始化向量的类型推断出来的。但是,当我尝试编写Matrix::zero()
构造函数时,由于要传递的唯一参数是大小,因此遇到了如何推断类型的问题。
impl<T> Matrix<T> {
pub fn zero(nrows: usize, ncols: usize) -> Matrix<T>
where T : Clone
{
let data: Vec<T> = vec![0; nrows*ncols];
Matrix::new(data, nrows, ncols)
}
}
尝试编译此错误消息:
error[E0308]: mismatched types
--> src/tools.rs:39:33
|
39 | let data: Vec<T> = vec![0; nrows*ncols];
| ^ expected type parameter, found integral variable
|
= note: expected type `T`
found type `{integer}`
我尝试了0 as T
和T::from(0)
,但这些问题仍无法解决。 (说实话,我还不明白为什么。)一种可能的解决方案是将函数定义更改为zero(_value: T, nrows: usize, ncols: usize)
并通过vec![_value; ...]
构造数据矢量,但这似乎很奇怪。
无论采用哪种解决方案,我的最终目标都是能够简单地编写
let a: Matrix<f32> = Matrix::zero(nrows, ncols);
// ... or ...
let b = Matrix<f32>::zero(nrows, ncols);
// ... or ...
let c = Matrix::zero<f32>(nrows, ncols);
// ... or something else?
答案 0 :(得分:3)
您可能想使用num板条箱,该板条为这种情况添加了特征。
类似的东西:
extern crate num;
use num::Zero;
impl<T> Matrix<T> {
pub fn zero(nrows: usize, ncols: usize) -> Matrix<T>
where T : Clone + Zero
{
let data: Vec<T> = vec![T::zero(); nrows*ncols];
Matrix::new(data, nrows, ncols)
}
}
可能会起作用,因为它将您的矩阵类型定义为受实现num::Zero
特征的类型所限制。这是在所有整数和浮点基元上实现的,也可以为自定义类型实现。
如果您不想导入num
条板箱,则可以手动定义此特征,如下所示,尽管它需要您自己为基元实现。
trait Zero {
fn zero() -> Self;
}
impl Zero for f32 {
fn zero() -> Self {
0.0
}
}
...