如何将Rust中的两个i16数字相加或相乘成更大的i32而不会溢出?

let a: i16 = i16::max_value();
let b: i16 = i16::max_value();
let c: i32 = a + b; // throws EO308 "Expected `u32`, found `u16`

最佳答案

Rust中没有积分提升或隐式强制转换,因此您必须手动进行所有类型转换。

对于类型转换,可以使用<value> as <type>。但是,如果目标类型是原始类型的超集并且将其转换不会丢失信息(例如您的案例),则可以使用<type>::from对其进行自我记录:

let a: i16 = i16::max_value();
let b: i16 = i16::max_value();
let c: i32 = i32::from(a) + i32::from(b);
assert_eq!(c, 65534);

这种特殊情况不会溢出,但是对于其他情况,您可以使用{integer}::checked_*()函数防止溢出:

let a: i16 = i16::max_value();
let b: i16 = i16::max_value();
let c: Option<i16> = a.checked_add(b);
assert_eq!(c, None); //overflow!

请注意,在调试版本中,默认情况下会溢出整数运算 panic 。

如果要包装算术,就像在旧的C语言中一样,则可以使用{integer}::wraping_*(),以及它可用于有符号和无符号值的额外好处。

let a: i16 = i16::max_value();
let b: i16 = i16::max_value();
let c: i16 = a.wrapping_add(b);
assert_eq!(c, -2);

09-25 18:38