通过 32 位整数索引向量

2023-11-24

在 Rust 中,向量的索引使用usize,所以写的时候

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

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

my_vec[index as usize]

但这写起来很乏味。理想情况下我会简单地超载[]运营商通过实施

impl<T> std::ops::Index<u32> for Vec<T> { ... }

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


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

这里基本上有两个问题:

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

当使用函数式编程风格时,通常不需要索引,因为您对迭代器进行操作。在这种情况下,事实是Vec只实现Index for usize真的没关系。

如果你的算法确实需要索引,那么为什么不使用usize?有很多方法可以从u32 to usize,在最后一刻进行转换是一种可能性,但还有其他网站可以进行转换,如果您发现(或创建它)阻塞点,则只需进行少量转换即可逃脱。

至少,这是 YAGNI 的观点。


就我个人而言,作为一个类型狂,我倾向于把事情绕得更远。我只是想添加semantic信息,因为让我们面对现实吧Vec<i32>只是没有任何意义。

Rust 提供了一种创建包装结构的简单方法:struct MyType(WrappedType);。就是这样。

一旦您有了自己的类型,添加索引就很容易了。有多种方法可以添加其他操作:

  • 如果只有少数操作有意义,那么显式添加是最好的。
  • if many operations are necessary, and you do not mind exposing the fact that underneath is a Vec<X>, then you can expose it:
    • 通过公开:struct MyType(pub WrappedType);,然后用户可以调用.0来访问它。
    • 通过实施AsRef and AsMut,或者创建一个吸气剂。
    • 通过实施Deref and DerefMut(这是隐含的,请确保您确实想要)。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 32 位整数索引向量 的相关文章

随机推荐