Go 整数类型详解🧮

Go 整数类型详解

一、核心重点(快速掌握)

序号 重点内容 备注说明
1 类型分类:有符号与无符号 int8, int16, int32, int64uint8, uint16, uint32, uint64
2 平台相关类型:int 和 uint 在32位系统是4字节,在64位系统是8字节
3 零值默认为0 未显式初始化的整数变量默认值为0
4 支持常量定义 使用 const 定义常量,不分配内存
5 类型转换必须显式 Go语言不允许隐式类型转换,如需转换必须使用强制类型转换
6 字面量支持多种进制 十进制、二进制(0b)、八进制(0o)、十六进制(0x
7 支持溢出检测(Go 1.21+) 使用 math 包中的 Add, Mul 等函数进行带溢出检查的运算

二、知识点详解(专题深入)

1、整数类型分类

1.1 有符号整数类型(Signed Integers)

类型名 所占字节数 取值范围
int8 1 -128 ~ 127
int16 2 -32768 ~ 32767
int32 4 -2147483648 ~ 2147483647
int64 8 -9223372036854775808 ~ 9223372036854775807

1.2 无符号整数类型(Unsigned Integers)

类型名 所占字节数 取值范围
uint8 1 0 ~ 255
uint16 2 0 ~ 65535
uint32 4 0 ~ 4294967295
uint64 8 0 ~ 18446744073709551615

注意点

  • uint8 是最常用的无符号类型之一,对应 ASCII 字符。
  • 尽量避免使用 intuint,除非你确实需要依赖平台特性。

实例代码:

package main

import "fmt"

func main() {
	var a int8 = 127
	var b uint8 = 255
	fmt.Println("a =", a) // 输出: a = 127
	fmt.Println("b =", b) // 输出: b = 255
}

2、平台相关类型:int 与 uint

类型名 所占字节数(32位系统) 所占字节数(64位系统)
int 4 8
uint 4 8

技巧

  • 如果你的程序对性能或内存敏感,建议使用固定大小的类型(如 int32int64)以确保跨平台一致性。
  • 对于数组索引、循环计数器等场景,推荐使用 int

实例代码:

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	fmt.Printf("Size of int: %d bytes\n", unsafe.Sizeof(0))   // 根据平台输出4或8
	fmt.Printf("Size of uint: %d bytes\n", unsafe.Sizeof(uint(0)))
}

注意点

  • unsafe.Sizeof 不计算动态内存,仅返回静态类型的大小。
  • 使用 intuint 时要特别注意跨平台兼容性问题。

3、整数字面量表示法

Go 支持多种进制的整数字面量表示方式:

进制类型 前缀示例 示例值
十进制 123
二进制 0b 0b1010
八进制 0o 0o755
十六进制 0x 0x1A3F

实例代码:

package main

import "fmt"

func main() {
	a := 123        // 十进制
	b := 0b1010     // 二进制
	c := 0o755      // 八进制
	d := 0x1A3F     // 十六进制

	fmt.Printf("a = %d, b = %d, c = %d, d = %d\n", a, b, c, d)
}

注意点

  • Go 1.13 开始支持 0b 表示二进制,之前版本不可用。
  • 下划线 _ 可用于增强可读性,例如:0b1010_1111

4、整数常量(const)

Go 中可以使用 const 关键字定义整数常量,具有以下特点:

  • 编译时常量,不占用运行时内存。
  • 可以跨越类型边界进行赋值,只要在目标类型范围内。

实例代码:

package main

import "fmt"

const (
	MaxInt8   = 1<<7 - 1  // 127
	MinInt8   = -1 << 7   // -128
	MaxUint16 = 1<<16 - 1 // 65535
)

func main() {
	var a int8 = MaxInt8
	var b uint16 = MaxUint16
	fmt.Println("a =", a)
	fmt.Println("b =", b)
}

注意点

  • 常量表达式中可以使用位移操作来简化数值定义。
  • 常量不能取地址,也不能使用 & 操作符。

5、类型转换必须显式

Go 不允许隐式类型转换,必须使用显式语法进行类型转换。

实例代码:

package main

import "fmt"

func main() {
	var a int = 100
	var b int32 = int32(a) // 显式转换
	fmt.Println("b =", b)
}

注意点

  • 转换可能导致数据丢失,应谨慎处理。
  • 使用 strconv 包可在字符串和整数之间转换。

6、溢出处理(Go 1.21+)

Go 1.21 引入了 math 包中的安全整数运算函数,可用于检测溢出。

支持函数列表:

函数名 功能描述
math.Add 加法并检测是否溢出
math.Sub 减法并检测是否溢出
math.Mul 乘法并检测是否溢出
math.Div 除法并检测是否溢出或除零错误
math.Mod 取模并检测是否溢出或除零错误

实例代码:

package main

import (
	"fmt"
	"math"
)

func main() {
	a := math.MaxInt64
	b := int64(1)
	sum, overflow := math.Add64(a, b)
	if overflow {
		fmt.Println("加法溢出!")
	} else {
		fmt.Println("sum =", sum)
	}
}

注意点

  • 该功能适用于金融、加密等高精度场景。
  • 旧版本 Go 需自行实现溢出判断逻辑。

7、常见陷阱与注意事项汇总

陷阱/问题 解决方案/建议
混合类型运算报错 显式转换其中一个操作数为相同类型
使用 int 造成跨平台问题 推荐使用固定大小类型,如 int32int64
误用 uint 导致负数问题 注意 uint 无法表示负数,可能导致死循环或逻辑错误
忽略溢出风险 使用 math 包中的安全运算函数(Go 1.21+)
字面量格式错误 使用正确前缀:0b0o0x
忘记初始化变量 Go 默认初始化为0,但显式初始化更清晰可靠

8、使用 iota 定义枚举常量(Enumerated Constants)

知识点:

  • iota 是 Go 中的预声明标识符,在 const 块中自动递增,通常用于定义枚举常量。
  • 每个 const 块中 iota 从 0 开始计数,遇到新的 const 块则重置为 0。
  • 可以通过位移等操作控制其值的增长方式。
类型 描述
枚举常量 使用 iota 实现常量自增机制

实例代码:

package main

import "fmt"

const (
	Red = iota    // 0
	Green         // 1
	Blue          // 2
)

func main() {
	fmt.Println("Red:", Red)    // 输出: 0
	fmt.Println("Green:", Green) // 输出: 1
	fmt.Println("Blue:", Blue)  // 输出: 2
}

多组枚举示例:

const (
	_ = iota
	First
	Second
	Third
)

const (
	A = iota + 1 // 1
	B            // 2
	C            // 3
)

func main() {
	fmt.Println("First:", First) // 输出: 1
	fmt.Println("C:", C)         // 输出: 3
}

高级用法:按位定义状态标志

const (
	Read    = 1 << iota // 1
	Write               // 2
	Execute             // 4
)

func main() {
	fmt.Printf("Read: %b\n", Read)    // 输出: 1 (二进制)
	fmt.Printf("Write: %b\n", Write)  // 输出: 10
	fmt.Printf("Execute: %b\n", Execute) // 输出: 100
}

注意点

  • 若不需要第一个值,可用 _ 忽略初始 iota 值。
  • 在不同 const 块之间,iota 会重新从 0 开始。
  • 不要在非 const 上下文中使用 iota,否则编译报错。

技巧

  • 利用 iota 和位运算可以高效定义权限、状态码、协议字段等。
  • 可结合注释与命名规范提升可读性。
posted @ 2025-06-25 07:46  红尘过客2022  阅读(34)  评论(0)    收藏  举报