在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
,但这意味着必须编写大量的函数包装器.有没有更优雅的方式来解决这个问题?
如果没有明确的用例,很难推荐最佳方法.
这里基本上有两个问题:
u32
用于指数吗?使用函数式编程样式时,通常不需要索引,因为您在迭代器上操作.在这种情况下,其实Vec
只实现Index
了usize
真的没关系.
如果您的算法确实需要索引,那么为什么不使用usize
?有很多方法可以转换u32
为usize
,在最后一刻转换可能是一种可能性,但是还有其他网站可以进行转换,如果你找到一个阻塞点(或创建它),你只能勉强逃脱转换.
至少,这是YAGNI的观点.
就个人而言,作为一个类型的怪物,我倾向于包装很多东西.我只想添加语义信息,因为让我们面对它Vec<i32>
并不意味着什么.
Rust提供了一种创建包装器结构的简单方法:struct MyType(WrappedType);
.而已.
拥有自己的类型后,添加索引很容易.有几种方法可以添加其他操作:
Vec<X>
,那么您可以公开它:
struct MyType(pub WrappedType);
用户可以调用.0
来访问它.AsRef
和AsMut
/或创建一个getter.Deref
和DerefMut
(这是隐含的,确保你真的想要).当然,打破封装后来会很烦人,因为它也会阻止不变量的维护,所以我认为它是最后的解决方案.
归档时间: |
|
查看次数: |
1753 次 |
最近记录: |