【发布时间】:2021-05-19 23:38:28
【问题描述】:
我目前学习 Rust 是为了好玩。我在 C/C++ 方面有一些经验,并且在使用泛型等更复杂范式的其他编程语言方面有其他经验。
背景
对于我的第一个项目(在教程之后),我想创建一个 N 维数组(或矩阵)数据结构来练习使用 Rust 进行开发。
这是迄今为止我的 Matrix 结构以及基本填充和新初始化的内容。
原谅缺少的边界检查和参数测试
pub struct Matrix<'a, T> {
data: Vec<Option<T>>,
dimensions: &'a [usize],
}
impl<'a, T: Clone> Matrix<'a, T> {
pub fn fill(dimensions: &'a [usize], fill: T) -> Matrix<'a, T> {
let mut total = if dimensions.len() > 0 { 1 } else { 0 };
for dim in dimensions.iter() {
total *= dim;
}
Matrix {
data: vec![Some(fill); total],
dimensions: dimensions,
}
}
pub fn new(dimensions: &'a [usize]) -> Matrix<'a, T> {
...
Matrix {
data: vec![None; total],
dimensions: dimensions,
}
}
}
我希望能够使用 New fn 创建一个“空”N 维数组。我认为使用 Option 枚举将是实现此目的的最佳方式,因为我可以用 None 填充 N 维,它会自动为这个 T 泛型分配空间。
那么归根结底就是能够为此设置条目。我发现IndexMut 和Index 特征看起来我可以做类似m[&[2, 3]] = 23 的事情。由于逻辑彼此相似,这里是IndexMut impl for Matrix。
impl<'a, T> ops::IndexMut<&[usize]> for Matrix<'a, T> {
fn index_mut(&mut self, indices: &[usize]) -> &mut Self::Output {
match self.data[get_matrix_index(self.dimensions, indices)].as_mut() {
Some(x) => x,
None => {
NOT SURE WHAT TO DO HERE.
}
}
}
}
理想情况下会发生的情况是值(如果存在)将被更改,即
let mut mat = Matrix::fill(&[4, 4], 0)
mat[&[2, 3]] = 23
这会将值设置为 0 到 23(上面的 fn 通过从 Some(x) 返回 &mut x 来实现)。但我也希望None 设置值,即
let mut mat = Matrix::new(&[4, 4])
mat[&[2, 3]] = 23
问题
最后,有没有办法让m[&[2,3]] = 23 成为可能,因为 Vec 结构需要分配内存?如果不是我应该改变什么,我怎么还能有一个带有“空”点的数组。在我尝试学习时接受任何建议。 :)
最后的想法
通过我的研究,Vec struct impls 我看到类型 T 是类型化的并且必须调整大小。这对于通过vec![pointer of T that is null but of size of T; total] 分配具有适当大小的 Vec 可能很有用。但我不确定如何做到这一点。
【问题讨论】:
-
您对
Index特征有什么看法?如果该索引处的值不存在,你会返回什么? -
我之所以问是因为可以根据需要实现
IndexMut,但由于IndexMut的输出类型必须匹配相应的Index特征,因此它会对Index实现产生令人不安的影响。 -
对于
Index特征,如果Option<T>枚举的值为None,我也会遇到同样的问题。我不知道该返回什么。目前我只是惊慌失措,但我不确定该怎么做这对 Rust 来说是惯用的,并且具有返回“空”指针或对用户有意义的东西的功能。 -
理想情况下,这意味着在
println!("{}", m[&[1, 1]]);等情况下,m[&[1, 1]]是选项枚举None它会出错,因为它会对“null”值或类似的东西执行 to_string .但对于功能,Index应该返回矩阵中该位置的值。
标签: rust