在Rust中包含负数

tin*_*ker 0 rust

我正在重写Rust中的C代码,它严重依赖u32变量并将它们包装起来.例如,我有一个像这样定义的循环:

#define NWORDS 24
#define ZERO_WORDS 11

int main()
{
    unsigned int i, j;

    for (i = 0; i < NWORDS; i++) {
        for (j = 0; j < i; j++) {
            if (j < (i-ZERO_WORDS+1)) {
            }
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,该if语句需要u32最初包含几个值i = 0.我遇到了这个wrapping_neg方法,但它似乎只是计算-self.是否还有更灵活的方式u32在Rust中使用包装?

She*_*ter 6

正如评论中提到的,您问题的字面答案是使用u32::wrapping_subu32::wrapping_add:

const NWORDS: u32 = 24;
const ZERO_WORDS: u32 = 11;

fn main() {
    for i in 0..NWORDS {
        for j in 0..i {
            if j < i.wrapping_sub(ZERO_WORDS).wrapping_add(1) {}
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我主张避免依赖包装操作,除非您正在执行散列/加密/压缩/类似的操作.包装操作不直观.例如,j < i-ZERO_WORDS+1没有与之相同的结果j+ZERO_WORDS < i+1.

更好的是重写逻辑.我甚至不知道if没有花费大量时间思考的情况下,表达将在何种情况下成立!

事实证明,条件被评估i=9, j=8,但不是i=10, j=0.也许所有这一切在实际代码中都更清晰,但是没有上下文它会让人很困惑.

这看起来有相同的逻辑,但对我来说似乎更容易理解:

i < ZERO_WORDS - 1 || i - j > ZERO_WORDS - 1;
Run Code Online (Sandbox Code Playgroud)

相比:

j < i.wrapping_sub(ZERO_WORDS).wrapping_add(1);
Run Code Online (Sandbox Code Playgroud)