我目前正在尝试优化代码的可读性,并且在索引数组但还需要使用负数时遇到了问题。这是例子:
解释,因为它很难阅读: 此代码尝试遍历向量中的每个元素并找到其左侧和右侧的元素。随后从左侧减去右侧并作为输出打印。如果索引在任何时候超出范围,它将被替换为
0
fn main() {
let vec = vec![1, 2, 3];
let mask = [-1, 1];
for i in 0..vec.len() {
let l_index = (i as i32 + mask[0]);
let left = if l_index >= 0 {vec.get(l_index as usize).unwrap_or(&0)}
else {&0};
let r_index = (i as i32 + mask[1]);
let right = if r_index >= 0 {vec.get(r_index as usize).unwrap_or(&0)}
else {&0};
println!("Sum: {}", *left as i32 - *right as i32);
}
}
预期结果:
Sum: -2
Sum: -2
Sum: 2
此代码不是我的代码的实际部分,只是一个示例。当我决定使用这些“掩模”或在二维网格中进行线性代数时,经常会出现此问题,因为您经常需要减去或添加可能的负值。
要点是,我必须总共进行 6 次类型转换,因为我需要对负数的支持,但还需要能够索引到向量中。
我还必须将索引方程提取到单独的行中:
let l_index = (i as i32 + mask[0]);
。否则我就会写vec.get(i + mask[0])
。
总之,我发现这段代码对于不熟悉它的人来说完全难以辨认。这种情况尤其不适用于主要代码库,但即使在我自己的代码库中,我也想遵循最佳实践。 我想找到一种方法来提高可读性,如果您需要负数功能以及安全索引数组的能力。 (我非常清楚您可以轻松更改我设置蒙版的方式,但是我遇到过这样的蒙版更大并且希望保持简单的情况。)
您可以使用
wrapping_add
: 来避免大多数强制转换和中间值
fn main() {
let vec = vec![1, 2, 3];
let mask = [-1i32 as usize, 1];
for i in 0..vec.len() {
let left = vec.get (i.wrapping_add (mask[0])).unwrap_or (&0);
let right = vec.get (i.wrapping_add (mask[1])).unwrap_or (&0);
println!("Sum: {}", *left as i32 - *right as i32);
}
}