2.1.1 什么是整型?
整型就是用来表示整数的类型,比如 0、1、-42、100 等。在仓颉中,整型分为两大类:
- 有符号整型:可以表示正数、负数和零(如
Int8、Int64) - 无符号整型:只能表示零和正数(如
UInt8、UInt64)
💡TIP
简单记忆:带 U 前缀的就是无符号(Unsigned),只能存非负数;不带 U 的可以存负数。
2.1.2 整型类型一览
| 类型 | 位数 | 表示范围 | 说明 |
|---|---|---|---|
Int8 |
8 | -2⁷ ~ 2⁷-1(-128 ~ 127) | |
Int16 |
16 | -2¹⁵ ~ 2¹⁵-1(-32768 ~ 32767) | |
Int32 |
32 | -2³¹ ~ 2³¹-1(-2147483648 ~ 2147483647) | |
Int64 |
64 | -2⁶³ ~ 2⁶³-1(-9223372036854775808 ~ 9223372036854775807) | 首选类型 |
IntNative |
平台相关 | 平台相关 | 与系统位宽一致 |
UInt8 |
8 | 0 ~ 2⁸-1(0 ~ 255) | |
UInt16 |
16 | 0 ~ 2¹⁶-1(0 ~ 65535) | |
UInt32 |
32 | 0 ~ 2³²-1(0 ~ 4294967295) | |
UInt64 |
64 | 0 ~ 2⁶⁴-1(0 ~ 18446744073709551615) | |
UIntNative |
平台相关 | 平台相关 | 与系统位宽一致 |
💡TIP
在不确定用哪种整型时,首选 Int64。原因:
- 表示范围足够大,不容易溢出
- 整数字面量默认推断为
Int64,可以避免不必要的类型转换
2.1.3 整数字面量
字面量就是代码中直接写出来的数值。仓颉支持 4 种进制写法:
| 进制 | 前缀 | 示例 | 十进制值 |
|---|---|---|---|
| 二进制 | 0b 或 0B |
0b00011000 |
24 |
| 八进制 | 0o 或 0O |
0o30 |
24 |
| 十进制 | 无前缀 | 24 |
24 |
| 十六进制 | 0x 或 0X |
0x18 |
24 |
可以用下划线 _ 作为分隔符,方便阅读:
Cangjie
let million = 1_000_000 // 更易读
let binary = 0b0001_1000 // 二进制也支持
超出范围会报错
如果字面量的值超出了变量类型的表示范围,编译器会报错:
Cangjie
let x: Int8 = 128 // ❌ Int8 最大是 127
let y: UInt8 = 256 // ❌ UInt8 最大是 255
let z: Int32 = 0x8000_0000 // ❌ 超出 Int32 范围
2.1.4 类型后缀
可以通过在数字后面加后缀来明确指定字面量的类型:
| 后缀 | 类型 | 后缀 | 类型 |
|---|---|---|---|
i8 |
Int8 |
u8 |
UInt8 |
i16 |
Int16 |
u16 |
UInt16 |
i32 |
Int32 |
u32 |
UInt32 |
i64 |
Int64 |
u64 |
UInt64 |
使用示例:
Cangjie
var x = 100i8 // x 是 Int8 类型,值为 100
var y = 0x10u64 // y 是 UInt64 类型,值为 16
var z = 0o432i32 // z 是 Int32 类型,值为 282
💡TIP
加后缀后就不需要再写 : Int8 这样的类型标注了,编译器能自动识别。
2.1.5 字符字节字面量
仓颉支持用 b'字符' 的形式来表示 UInt8 类型的值,本质上是取该 ASCII 字符的编码值:
Cangjie
main() {
var a = b'x' // a 是 UInt8 类型,值为 120('x' 的 ASCII 码)
var b = b'\n' // b 是 UInt8 类型,值为 10(换行符的 ASCII 码)
var c = b'\u{78}' // c 是 UInt8 类型,值为 120(0x78 = 120)
c = b'\u{90}' - b'\u{66}' + c // 可以参与运算
}
其中 \u{} 是用十六进制数表示字符编码的转义写法,花括号内填写十六进制数值,编译器会将其转换为对应的 UInt8 值。例如 \u{78} 就等于十六进制 0x78,即十进制 120。
ℹ️NOTE
\u{}内最多两位十六进制数,且值必须小于 256(因为UInt8最大就是 255)- 只能使用 ASCII 字符,不能用于中文等多字节字符
2.1.6 小结
| 概念 | 要点 |
|---|---|
| 整型分类 | 有符号(Int 系列)和无符号(UInt 系列) |
| 首选类型 | Int64,默认推断类型 |
| 字面量进制 | 二进制 0b、八进制 0o、十进制、十六进制 0x |
| 类型后缀 | i8/i16/i32/i64 和 u8/u16/u32/u64 |
| 字节字面量 | b'x' 表示 ASCII 字符的 UInt8 值 |
2.1.7 常见问题
Q1:`Int64` 的范围太大了记不住怎么办?
不需要记具体数字,只需要知道:
Int64大约能表示 ±9 百亿亿(9 后面跟 18 个 0)- 日常开发中基本不会溢出
- 如果实在担心,记住
Int32的范围(±21 亿)就够了,大多数场景用Int32都不会超
Q2:为什么整数默认是 `Int64` 而不是 `Int32`?
这是为了安全。64 位整数能表示的范围比 32 位大得多,不容易溢出。虽然会多用一点内存,但对于大多数程序来说,这点内存可以忽略不计。
Q3:有符号(`Int`)和无符号(`UInt`)怎么选?
- 默认用有符号(
Int系列),因为大多数场景需要负数 - 只有确定不会出现负数时,才考虑无符号(
UInt系列),比如表示年龄、ID 等 - 无符号类型可以多存一倍的证书范围
⚠️WARNING
无符号类型和有符号类型混用时要小心,容易出 Bug。新手建议无脑用有符号。
Q4:类型后缀什么时候用?
当你希望明确指定一个数字的类型时用。最常见场景:
Cangjie
let x = 100i8 // 明确告诉编译器:这个数字是 Int8 类型
let y = 0xffu64 // 明确告诉编译器:这个数字是 UInt64 类型
用后缀的好处是:不需要再写 : Int8 这样的类型标注,代码更简洁。
