为什么 u32 不能加减 i32?[已结束]

Why can't u32 add or subtract i32? [closed]

提问人:Kodra 提问时间:10/12/2023 最后编辑:John KugelmanKodra 更新时间:10/12/2023 访问量:156

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章来用事实和引文来回答。

上个月关闭。

let a: u32 = 10;
let b: i32 = 100;
let c = a - b;

即使是这个简单的操作也不起作用。 只是无法操作.但我真的很想知道这背后的设计原则是什么。我不认为比.例如:u32i32u32 - i32u32 - u32

let a: u32 = 10;
let b: u32 = 100;
let c = a - b;

可以编译,但它在运行时会死机。那么,为什么 Rust 对不同数值类型之间的操作如此偏执呢?处理这个问题的惯用方法是什么,随处可见?as

我发现即使是选中的操作也不适用于不同的数值类型,这有点疯狂。

let a: u32 = 10;
let b: i32 = 100;
let c = a.checked_sub(b);
rust 类型转换 数值 算术表达式

评论

8赞 Jmb 10/12/2023
结果应该是什么?应该是还是别的什么?u32 - i32u32i32
3赞 Aleksander Krauze 10/12/2023
如果您可以添加一个有符号的号码和一个未签名的号码,结果应该是什么?签名号码?无符号?有模棱两可的地方。而 rust 就是要消除隐含的歧义,转而支持显式。您可以(并且应该)通过手动执行强制转换来选择输出类型。请注意,使用实际上不被认为是惯用的,您应该使用 和 特征来确保您不会被过溢或下溢默默地击中。asFromTryFrom
5赞 Aleksander Krauze 10/12/2023
我不知道我可以添加更多内容,但 rust 值是明确的。这只是生锈迫使您预先考虑边缘情况的另一个示例,这可以使您以后免于讨厌的错误。
1赞 Kodra 10/12/2023
我真的不明白为什么,对 Rust 来说也不够明确。他们已经“检查”了方法名称......?或者有没有一种方法可以解决我错过的这个用例?虽然不够明确,但恐慌,可以吗?checked_addchecked_subxxx_addu32.checked_add(i32)u32 - u32
2赞 John Kugelman 10/12/2023
该词表示这些函数检测到溢出并返回一个错误以强制您处理它,而不是惊慌失措或静默包装。他们没有解决关于结果应该是 还是 的歧义。checkedResultu32i32

答:

7赞 Colonel Thirty Two 10/12/2023 #1

这并不是有符号与无符号所独有的;Rust 甚至不允许你将不同大小的整数加在一起:

fn main() {
   println!("{}", 5u32 + 10u16);
}
error[E0308]: mismatched types
 --> src/main.rs:3:26
  |
3 |    println!("{}", 5u32 + 10u16);
  |                          ^^^^^ expected `u32`, found `u16`

error[E0277]: cannot add `u16` to `u32`

对于将有符号值添加到无符号值的特定情况,有 checked_add_signedoverflowing_add_signedsaturating_add_signedwrapping_add_signed 等函数。

好吧,人们可能不同意这一点,但u32.checked_sub(i32)肯定应该是 u32?我真的不认为它如此模棱两可。

你在自己的评论中承认,你认为不是每个人都会同意一个明显的行为,这确实是问题的关键。C 和 C++ 在整数提升方面有一些笨拙的规则 - 像表达式中的杂散非限定文字会将表达式转换为有符号整数。Rust 决定让一切变得明确。123

评论

0赞 cafce25 10/12/2023
与其说是 Rust “甚至不会让你添加不同大小的整数”,不如说是 core 没有实现相关特征。它可以很好地实现具有不同 rhs 运算符的 add