如何将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);