我正在尝试创建一个Matrix结构,并且我想覆盖Index运算符以让我拥有矩阵样式的索引。
例如:
let m = Matrix { ... DATA ... }
let entry = m[0,0]
Run Code Online (Sandbox Code Playgroud)
我的结构是这样的:
struct Matrix {
cols: usize,
rows: usize,
data: Vec<f32>
}
Run Code Online (Sandbox Code Playgroud)
我一直在研究Index trait,但我不知道如何使这项工作发挥作用?另外,我希望能够在每个维度等中获取范围。
简而言之,你不能这样做。的Index性状的定义为:
pub trait Index<Idx: ?Sized> {
type Output: ?Sized;
fn index(&self, index: Idx) -> &Self::Output;
}
Run Code Online (Sandbox Code Playgroud)
也就是说,它需要一个单一类型的参数Idx。您可以做的最接近的是使用元组,它是一种包含多个值的单一类型:
impl std::ops::Index<(usize, usize)> for Matrix {
type Output = f32;
fn index(&self, idx: (usize, usize)) -> &f32 {
// or as appropriate for row- or column-major data
&self.data[idx.0 * self.cols + idx.1]
}
}
Run Code Online (Sandbox Code Playgroud)
它会被称为
matrix[(0, 1)]
Run Code Online (Sandbox Code Playgroud)
bluss指出的是,多阵列板条箱使用两个元件阵列而不是一个元组。这可能更容易输入,因为您只需按两次方括号即可:
impl std::ops::Index<[usize; 2]> for Matrix {
type Output = f32;
fn index(&self, idx: [usize; 2]) -> &f32 {
// or as appropriate for row- or column-major data
&self.data[idx[0] * self.cols + idx[1]]
}
}
Run Code Online (Sandbox Code Playgroud)
它被称为 like matrix[[0, 1]]。重要的是,仍然只有一个值作为参数提供给index。
根据需要进行重复执行Range,RangeTo,RangeFrom,和RangeFull。这些都是单一类型,因此您可以将其称为 like matrix[5..],无论这可能意味着什么。
另一种可能性是使用二维数组样式索引,如m[0][1]. 这绝对是可能的——在你的情况下甚至很容易。您的Index实现只需要返回可再次索引的内容。代码:
use std::ops::Index;
struct Matrix {
cols: usize,
rows: usize,
data: Vec<f32>
}
impl Index<usize> for Matrix {
type Output = [f32];
fn index(&self, index: usize) -> &Self::Output {
&self.data[index * self.cols .. (index+1) * self.cols]
}
}
fn main() {
let m = Matrix {
cols: 2,
rows: 2,
data: vec![1., 2., 3., 4.],
};
println!("{} {}", m[0][0], m[0][1]);
println!("{} {}", m[1][0], m[1][1]);
}
Run Code Online (Sandbox Code Playgroud)
这种风格在 Java 和 C 等语言中更为常见。
| 归档时间: |
|
| 查看次数: |
1286 次 |
| 最近记录: |