我正在重写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中使用包装?
正如评论中所提到的,您问题的字面答案是使用u32::wrapping_sub和u32::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)