rust - 手动迭代时如何避免下溢陷阱?
问题描述
下面的代码会因为j
输入为usize
.
fn foo(vec: &Vec<i32>) {
let mut i = 0;
let mut j = vec.len() - 1;
while i < j {
while i < j && !some_condition(vec[i]) {
i += 1;
}
while i < j && !some_condition(vec[j]) {
j -= 1;
}
if i < j {
vec.swap(i, j);
i += 1;
j -= 1;
}
}
}
foo(&vec![]);
大多数情况下,迭代器有助于避免此类问题。但是当我们必须手动迭代索引时,我们真的需要小心。我可以检查vec
前面的大小以避免恐慌。但这里真正的问题是我倾向于认为即使没有空检查,程序也会按预期工作,直到角落案例咬我。所以我想知道在 Rust 中是否有任何惯用的方式来做这种事情。
解决方案
您可以查看saturating_sub
或checked_sub
:
fn foo(vec: &Vec<i32>) {
let mut i = 0;
let mut j = vec.len().saturating_sub(1);
while i < j {
// Some other logic
i += 1;
// EITHER
j.saturating_sub(1); // avoid getting below 0
//OR
j = j.checked_sub(1).expect("usize underflow");
}
}
foo(&vec![]);
如果您想要一些更复杂的处理而不是.expect()
您可以使用:
j = j.checked_sub(1).ok_or_else(|| some_your_error_creator())?;
这似乎更惯用,但需要一些额外的错误处理工作。
推荐阅读
- html - 如何通过 html 代码同时发送两个请求?
- javascript - 每个地区的人都一样的Javascript倒计时
- html - 如何正确设置表格中 tbody 元素的背景颜色?
- android - Flutter WebView App 不响应我的触摸事件
- javascript - 当我更改状态时,为什么排序不能正常工作?
- angular - Why does select dropdown show empty default in Angular 8 after http call?
- python - 如何将张量对象传递给接受数据类型为 uint 的图像的函数
- python-3.x - Discord.py 发送空白 .txt 文件
- java - ClassNotFoundException: javax.annotation.Generated with JDK 11
- python - 从 main.kv 文件 KivyMD 获取 id