整数类型
Move 提供六种无符号整数类型,没有有符号整数。所有整数类型都具有 copy、drop 和 store 能力,是构建数值逻辑的基础。
整数类型一览
| 类型 | 位宽 | 范围 |
|---|---|---|
u8 | 8位 | 0 ~ 255 |
u16 | 16位 | 0 ~ 65,535 |
u32 | 32位 | 0 ~ 4,294,967,295 |
u64 | 64位 | 0 ~ 18,446,744,073,709,551,615 |
u128 | 128位 | 0 ~ 2¹²⁸-1 |
u256 | 256位 | 0 ~ 2²⁵⁶-1 |
整数字面量
整数字面量可以使用后缀指定类型,也可以使用下划线分隔提高可读性:
module book::int_literals;
#[test]
fun literals() {
let a: u8 = 255;
let b = 1_000_000u64; // 下划线分隔
let c = 0xFF_u8; // 十六进制
let d: u128 = 1_000_000_000_000;
let e: u256 = 0;
assert_eq!(a, 255);
assert_eq!(b, 1000000);
}
算术运算符
| 运算符 | 说明 | 示例 |
|---|---|---|
+ | 加法 | 10 + 20 |
- | 减法 | 30 - 10 |
* | 乘法 | 5 * 6 |
/ | 整除 | 100 / 3 → 33 |
% | 取余 | 100 % 3 → 1 |
位运算符
| 运算符 | 说明 | 示例 |
|---|---|---|
& | 按位与 | 0xFF & 0x0F → 0x0F |
| | 按位或 | 0xF0 | 0x0F → 0xFF |
^ | 按位异或 | 0xFF ^ 0x0F → 0xF0 |
<< | 左移 | 1 << 3 → 8 |
>> | 右移 | 16 >> 2 → 4 |
比较运算符
| 运算符 | 说明 |
|---|---|
== | 等于 |
!= | 不等于 |
< | 小于 |
> | 大于 |
<= | 小于等于 |
>= | 大于等于 |
综合示例
module book::primitive_examples;
#[test]
fun primitives() {
let a: u8 = 255;
let b: u64 = 1_000_000;
let c: u128 = 1_000_000_000_000;
let d: u256 = 0;
let sum = 10u64 + 20;
let diff = 30u64 - 10;
let product = 5u64 * 6;
let quotient = 100u64 / 3;
let remainder = 100u64 % 3;
}
溢出保护
Move 的整数运算在运行时具有 溢出保护。当运算结果超出类型范围时,程序会产生运行时错误(abort),而不是静默地回绕(wrapping):
module book::overflow;
#[test]
#[expected_failure(abort_code = /* arithmetic error */)]
fun overflow() {
let max: u8 = 255;
let _result = max + 1; // 运行时 abort,不会回绕为 0
}
这一设计确保了链上资产运算的安全性,避免因溢出导致的漏洞。
类型推断与显式标注
Move 编译器通常可以根据上下文推断变量类型,但在某些情况下需要显式标注:
module book::type_inference;
#[test]
fun inference() {
let a = 42; // 编译器从使用场景推断类型
let b: u64 = 42; // 显式标注为 u64
let c = 42u8; // 通过后缀指定为 u8
let d = (42 as u128); // 通过 as 指定为 u128
assert_eq!(b, (a as u64));
}
当编译器无法推断类型时(例如变量未被使用,或者存在多种可能的类型),你需要显式标注类型。
小结
- 整数类型:u8、u16、u32、u64、u128、u256,全部为无符号
- 字面量:后缀指定类型、下划线分隔、十六进制
- 运算符:算术(+、-、*、/、%)、位运算(&、|、^、<<、>>)、比较(==、!=、<、>、<=、>=)
- 溢出保护:运行时检测溢出并 abort,而非静默回绕