在 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(使用前将#替换为@)