在 Rust 中索引向量时进行繁琐的类型转换

问题描述 投票:0回答:1

我目前正在尝试优化代码的可读性,并且在索引数组但还需要使用负数时遇到了问题。这是例子:

示例案例

解释,因为它很难阅读: 此代码尝试遍历向量中的每个元素并找到其左侧和右侧的元素。随后从左侧减去右侧并作为输出打印。如果索引在任何时候超出范围,它将被替换为

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])

问题

总之,我发现这段代码对于不熟悉它的人来说完全难以辨认。这种情况尤其不适用于主要代码库,但即使在我自己的代码库中,我也想遵循最佳实践。 我想找到一种方法来提高可读性,如果您需要负数功能以及安全索引数组的能力。 (我非常清楚您可以轻松更改我设置蒙版的方式,但是我遇到过这样的蒙版更大并且希望保持简单的情况。)

游乐场

rust type-conversion readability
1个回答
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);
    }
}

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.