根据具体情况的行为
overflow-checks
是一个较为粗糙的工具:它是一个全局设置,影响整个程序。
通常情况下,你可能希望根据不同的上下文来区别处理整数溢出:有时环绕是正确的选择,而有时恐慌更为可取。
wrapping_
方法
你可以通过使用 wrapping_
方法1在每次操作的基础上选择执行环绕算术。
例如,你可以使用 wrapping_add
来带环绕地添加两个整数:
#![allow(unused)] fn main() { let x = 255u8; let y = 1u8; let sum = x.wrapping_add(y); assert_eq!(sum, 0); }
saturating_
方法
或者,你可以使用 saturating_
方法选择执行饱和算术。
饱和算术不会进行环绕,而是会返回整数类型的最大或最小值。例如:
#![allow(unused)] fn main() { let x = 255u8; let y = 1u8; let sum = x.saturating_add(y); assert_eq!(sum, 255); }
由于 255 + 1
等于 256
,这超过了 u8::MAX
,所以结果就是 u8::MAX
(即255)。
对于下溢也是如此:0 - 1
是 -1
,这小于 u8::MIN
,因此结果就是 u8::MIN
(即0)。
你无法通过 overflow-checks
配置文件设置来获得饱和算术——在执行算术操作时,你必须明确选择它。
参考资料
- 本节练习位于
exercises/02_basic_calculator/09_saturating
1
你可以将方法视为“附着”到特定类型的函数。 我们将在下一章中涵盖方法(以及如何定义它们)。