通过32位整数索引向量

Hen*_*ler 4 rust

在Rust中,向量使用索引usize,因此在写入时

let my_vec: Vec<String> = vec!["Hello", "world"];
let index: u32 = 0;
println!("{}", my_vec[index]);
Run Code Online (Sandbox Code Playgroud)

你得到一个错误,因为索引应该是类型usize.我知道这可以通过显式转换索引来修复usize:

my_vec[index as usize]
Run Code Online (Sandbox Code Playgroud)

但这写起来很乏味.理想情况下,我只是[]通过实现来重载运算符

impl<T> std::ops::Index<u32> for Vec<T> { ... }
Run Code Online (Sandbox Code Playgroud)

但这是不可能的,因为Rust禁止这样做(因为特征和结构都不是本地的).我能看到的唯一选择是创建一个包装类Vec,但这意味着必须编写大量的函数包装器.有没有更优雅的方式来解决这个问题?

Mat*_* M. 6

如果没有明确的用例,很难推荐最佳方法.

这里基本上有两个问题:

  • 你真的需要索引吗?
  • 你真的需要u32用于指数吗?

使用函数式编程样式时,通常不需要索引,因为您在迭代器上操作.在这种情况下,其实Vec只实现Indexusize真的没关系.

如果您的算法确实需要索引,那么为什么不使用usize?有很多方法可以转换u32usize,在最后一刻转换可能是一种可能性,但是还有其他网站可以进行转换,如果你找到一个阻塞点(或创建它),你只能勉强逃脱转换.

至少,这是YAGNI的观点.


就个人而言,作为一个类型的怪物,我倾向于包装很多东西.我只想添加语义信息,因为让我们面对它Vec<i32>并不意味着什么.

Rust提供了一种创建包装器结构的简单方法:struct MyType(WrappedType);.而已.

拥有自己的类型后,添加索引很容易.有几种方法可以添加其他操作:

  • 如果只有少数操作有意义,那么明确添加是最好的.
  • 如果需要进行许多操作,并且您不介意暴露下面是a的事实Vec<X>,那么您可以公开它:
    • 通过公开:struct MyType(pub WrappedType);用户可以调用.0来访问它.
    • 通过实现AsRefAsMut/或创建一个getter.
    • 通过实施DerefDerefMut(这是隐含的,确保你真的想要).

当然,打破封装后来会很烦人,因为它也会阻止不变量的维护,所以我认为它是最后的解决方案.