reflect
reflect 包实现了运行时反射机制。它允许程序在运行时检查和操作具有任意类型的对象。其典型用途是:获取一个静态类型为 interface{}(空接口)的值,并通过调用 TypeOf 函数来提取其动态类型信息(该函数返回一个 Type 类型)。
调用 ValueOf 函数会返回一个 Value 类型,它代表了该值的运行时数据(包括值和类型信息)。
Zero 函数接收一个 Type 类型作为参数,并返回一个代表该类型零值的 Value。
核心目的:
动态类型检查与操作: 在编译时无法确定具体类型的情况下(例如处理
interface{}),在运行时获取类型信息(Type)和操作值(Value)。元编程: 编写能够处理任意类型数据的通用代码(如序列化/反序列化库、ORM框架、依赖注入容器等)。
1 常量
const Ptr = Pointer在 Go 语言的早期版本中,反射系统使用
Ptr作为表示指针类型的常量名后来为了代码清晰性和一致性,Go 团队决定将
Ptr重命名为Pointer这个常量定义是为了保持向后兼容性而保留的
2 函数
2.1 func Copy(dst, src Value) int
Copy 函数用于将源切片或数组的内容复制到目标切片或数组中,直到目标被填满或源被耗尽。返回实际复制的元素数量。
参数说明
dst Value:目标值,必须是切片或数组类型src Value:源值,必须是切片或数组类型(特殊情况:源可以是字符串,当目标元素类型为uint8时)
返回值
int:实际复制的元素数量
注意事项
目标和源必须都是切片或数组类型
目标和源的元素类型必须相同
如果目标是数组且不可设置(
CanSet() == false),会引发 panic特殊规则:当目标元素类型为
uint8时,源可以是字符串(相当于[]byte转换)
2.2 func DeepEqual(x, y any) bool
DeepEqual 递归比较两个值是否"深度(值)相等",比普通的 == 操作符更深入。它遵循以下规则:
比较规则
数组:对应元素深度相等
结构体:所有字段(包括未导出字段)深度相等
函数:只有两者都为 nil 时才相等
接口:持有的具体值深度相等
映射:
两者都为 nil 或都不为 nil
长度相同
相同键映射到深度相等的值
指针:
指针值相等(==)
或指向深度相等的值
切片:
两者都为 nil 或都不为 nil
长度相同
指向相同底层数组或对应元素深度相等
注意:
[]byte{}和[]byte(nil)不相等
基本类型:使用
==操作符比较
特殊情况
NaN 值:
math.NaN() != math.NaN(),但包含 NaN 的指针相等循环引用:检测到循环时认为指针相等
函数:非 nil 函数总是不相等(即使同一个函数)
2.3 func Swapper(slice any) func(i, j int)
Swapper 返回一个用于交换切片中元素的函数。该函数接收两个索引参数 i 和 j,交换切片中这两个位置的元素。
参数说明
slice any:必须是切片类型
返回值
func(i, j int):交换函数,用于交换指定索引的元素
注意事项
如果传入的不是切片类型,会引发 panic
交换函数不检查索引是否越界(调用时需确保索引有效)
返回的函数会修改原始切片内容
2.4 最佳实践总结
2.4.1 reflect.Copy
reflect.Copy优先使用内置的
copy()函数(类型安全)仅当处理
interface{}类型时使用反射版本注意目标容量限制,避免数据截断
特殊场景:字符串到
[]byte的转换
2.4.2 reflect.DeepEqual
reflect.DeepEqual测试中用于复杂结构的比较
注意未导出字段也会被比较
对于包含浮点数的结构,考虑自定义比较函数
性能敏感场景避免使用(递归比较开销大)
2.4.3 reflect.Swapper
reflect.Swapper实现排序算法时的便捷工具
比手动交换更简洁
注意只适用于切片,不适用于数组
3 类型
3.1 Type接口
reflect.Type 是 Go 反射系统的核心接口,用于表示 Go 类型的元信息。它提供了丰富的方法来查询类型的各种属性,是运行时类型检查和分析的基础。
基础信息查询
Kind()
返回类型的底层种类
Kind
所有类型
优先使用此方法判断类型
reflect.TypeOf(42).Kind() -> reflect.Int
Name()
返回类型名称(仅定义类型)
string
所有类型
非定义类型返回空字符串
reflect.TypeOf("").Name() -> "string" (预定义类型有名称)
PkgPath()
返回定义类型的包路径
string
定义类型
非定义类型返回空字符串
reflect.TypeOf(time.Time{}).PkgPath() -> "time"
String()
返回类型的字符串表示
string
所有类型
格式不保证唯一性,用于调试
reflect.TypeOf([]int{}).String() -> "[]int"
Size()
返回类型值的内存大小
uintptr
所有类型
对于引用类型,返回的是描述符大小
reflect.TypeOf(int64(0)).Size() -> 8
Align()
返回内存分配时的对齐字节数
int
所有类型
reflect.TypeOf(int64(0)).Align() -> 8
FieldAlign()
返回作为结构体字段时的对齐字节数
int
所有类型
reflect.TypeOf(int64(0)).FieldAlign() -> 8
类型关系检查
Implements(u Type)
检查是否实现某接口
bool
所有类型
参数u必须是接口类型
dogType.Implements(speakerType) -> true
AssignableTo(u Type)
检查是否可赋值给目标类型
bool
所有类型
遵循Go赋值规则
intType.AssignableTo(floatType) -> false
ConvertibleTo(u Type)
检查是否可转换为目标类型
bool
所有类型
转换可能丢失精度或溢出
intType.ConvertibleTo(floatType) -> true
Comparable()
检查类型值是否可比较
bool
所有类型
可比较类型才可用==操作符
sliceType.Comparable() -> false
复合类型操作
结构体操作:
NumField()
返回结构体字段数量
int
Struct
非结构体类型调用会panic
userType.NumField() -> 2
Field(i int)
返回结构体第i个字段
StructField
Struct
i必须在[0, NumField())内
userType.Field(0).Name -> "ID"
FieldByName(name string)
按名称查找结构体字段
(StructField, bool)
Struct
userType.FieldByName("Name") -> (StructField, true)
FieldByNameFunc(match func(string) bool)
使用函数匹配字段名
(StructField, bool)
Struct
略
FieldByIndex(index []int)
按索引序列查找嵌套字段
StructField
Struct
索引序列表示嵌套访问路径
略
函数操作:
NumIn()
返回函数参数数量
int
Func
非函数类型调用会panic
funcType.NumIn() -> 2
In(i int)
返回第i个参数类型
Type
Func
i必须在[0, NumIn())内
funcType.In(0) -> int
NumOut()
返回函数返回值数量
int
Func
非函数类型调用会panic
funcType.NumOut() -> 1
Out(i int)
返回第i个返回值类型
Type
Func
i必须在[0, NumOut())内
funcType.Out(0) -> bool
IsVariadic()
检查是否为可变参数函数
bool
Func
非函数类型调用会panic
funcType.IsVariadic() -> true
容器操作:
Elem()
返回容器元素类型
Type
Array, Chan, Map, Ptr, Slice
非容器类型调用会panic
sliceType.Elem() -> int
Key()
返回映射的键类型
Type
Map
非映射类型调用会panic
mapType.Key() -> string
Len()
返回数组长度
int
Array
非数组类型调用会panic
arrayType.Len() -> 3
ChanDir()
返回通道方向
ChanDir
Chan
非通道类型调用会panic
chanType.ChanDir() -> reflect.BothDir
数值类型专用方法
Bits()
返回类型位数
int
Int*, Uint*, Float*, Complex*
非数值类型调用会panic
intType.Bits() -> 64
OverflowInt(x int64)
检查整数x是否超出类型范围
bool
Int*, Uint*
非整数类型调用会panic
int8Type.OverflowInt(128) -> true
OverflowUint(x uint64)
检查无符号整数x是否超出范围
bool
Uint*
非无符号整数类型调用会panic
uint8Type.OverflowUint(256) -> true
OverflowFloat(x float64)
检查浮点数x是否超出范围
bool
Float*
非浮点类型调用会panic
float32Type.OverflowFloat(1e100) -> true
OverflowComplex(x complex128)
检查复数x是否超出范围
bool
Complex*
非复数类型调用会panic
complex64Type.OverflowComplex(complex(1e100,0)) -> true
其他方法
CanSeq()
是否可迭代(Go1.22+)
bool
所有类型
用于检查是否支持Seq迭代
sliceType.CanSeq() -> true
CanSeq2()
是否可键值迭代(Go1.22+)
bool
所有类型
用于检查是否支持Seq2迭代
mapType.CanSeq2() -> true
3.1.1 ArrayOf(length int, elem Type) Type
功能:创建数组类型 参数:
length int:数组长度elem Type:元素类型
返回值:数组类型 注意事项:
长度必须为正整数
元素类型不能为无效类型
总大小不能超过可用地址空间
3.1.2 ChanOf(dir ChanDir, t Type) Type
功能:创建通道类型 参数:
dir ChanDir:通道方向(reflect.RecvDir,reflect.SendDir,reflect.BothDir)t Type:元素类型
返回值:通道类型 注意事项:
元素类型不能超过 64KB 大小限制
元素类型必须为有效类型
3.1.3 FuncOf(in, out []Type, variadic bool) Type
功能:创建函数类型 参数:
in []Type:输入参数类型out []Type:输出结果类型variadic bool:是否可变参数
返回值:函数类型 注意事项:
可变参数时,最后一个输入参数必须是切片类型
参数类型不能为无效类型
3.1.4 MapOf(key, elem Type) Type
功能:创建映射类型 参数:
key Type:键类型elem Type:值类型
返回值:映射类型 注意事项:
键类型必须可比较(实现
==操作符)键类型不能为无效类型
3.1.5 SliceOf(t Type) Type
功能:创建切片类型 参数:
t Type:元素类型
返回值:切片类型 注意事项:
元素类型必须为有效类型
3.1.6 StructOf(fields []StructField) Type
功能:创建结构体类型 参数:
fields []StructField:字段定义
返回值:结构体类型 注意事项:
不支持导出未导出字段
不支持嵌入字段的方法提升
字段偏移量会自动计算
3.1.7 PointerTo(t Type) Type (Go 1.18+)
功能:创建指针类型 参数:
t Type:指向的类型
返回值:指针类型 注意事项:
替代已弃用的
PtrTo类型必须为有效类型
3.1.8 TypeFor[T any]() Type (Go 1.22+)
功能:获取泛型类型表示 返回值:类型表示 注意事项:
用于泛型场景的类型获取
比
TypeOf更类型安全
3.1.9 func TypeOf(i any) Type
TypeOf 返回一个 reflect.Type 值,该值表示参数 i 的动态类型(运行时实际类型)。返回值是一个接口类型,提供了对类型信息的全面访问能力。
参数说明
i any:任意类型的值(通常为空接口interface{})可以是基本类型、复合类型、函数、接口等任何 Go 值
可以接收指针、结构体、切片等任意值
返回值
Type:表示i的动态类型的reflect.Type接口值特殊返回值:当
i是未赋值的nil接口时(var i interface{}),返回nil
3.2 Value类型
reflect.Value 是 Go 反射系统的核心类型,它封装了 Go 值的运行时表示,提供了操作值的强大能力。
3.2.1 func ValueOf(i any) Value
功能:创建 Value 实例
参数:i any - 任意 Go 值
返回值:表示该值的 Value
注意事项:
接收任何类型的值
包含接口的运行时类型信息
对于
nil接口返回零值Value
3.2.2 func Zero(typ Type) Value
功能:创建类型零值的 Value
参数:typ Type - 目标类型
返回值:零值 Value
注意事项:
返回的值不可设置
对于指针类型返回
nil
3.2.3 func New(typ Type) Value
功能:创建指向类型零值的指针 Value
参数:typ Type - 目标类型
返回值:指向新分配值的指针 Value
注意事项:
返回的值可设置
相当于
&new(T)
函数名
功能描述
参数说明
返回值
注意事项
ValueOf(i any)
创建值的反射表示
i: 任意值
Value
返回值的运行时表示
Zero(typ Type)
创建类型零值
typ: 目标类型
Value
返回的值不可设置
New(typ Type)
创建指向类型零值的指针
typ: 目标类型
Value
返回指针的 Value,可设置
NewAt(typ Type, p unsafe.Pointer)
在指定地址创建指针
typ: 类型, p: 内存地址
Value
用于访问特定内存地址
MakeChan(typ Type, buffer int)
创建通道
typ: 通道类型, buffer: 缓冲区大小
Value
通道元素类型必须有效
MakeFunc(typ Type, fn func(args []Value) (results []Value))
动态创建函数
typ: 函数类型, fn: 实现函数
Value
函数签名必须匹配
MakeMap(typ Type)
创建空映射
typ: 映射类型
Value
键类型必须可比较
MakeMapWithSize(typ Type, n int)
创建预分配大小的映射
typ: 映射类型, n: 初始容量
Value
性能优化用
MakeSlice(typ Type, len, cap int)
创建切片
typ: 切片类型, len: 长度, cap: 容量
Value
返回可设置的切片
SliceAt(typ Type, p unsafe.Pointer, n int)
在地址创建切片
typ: 切片类型, p: 地址, n: 长度
Value
用于底层内存操作
3.2.4 值获取方法
3.2.4.1 Interface() any
功能:将 Value 转换为 interface{}
注意事项:
需要值可导出或可寻址
返回原始值的副本
3.2.4.2 类型特定获取方法
Int() int64:获取整数值Uint() uint64:获取无符号整数值Float() float64:获取浮点数值Bool() bool:获取布尔值String() string:获取字符串值Bytes() []byte:获取字节切片值Complex() complex128:获取复数值
3.2.5 值设置方法
3.2.5.1 Set(x Value)
功能:设置值(需可设置) 前提:
v.CanSet() == truex类型可赋值给v类型
3.2.5.2 类型特定设置方法
SetInt(x int64)SetUint(x uint64)SetFloat(x float64)SetBool(x bool)SetString(x string)SetBytes(x []byte)SetComplex(x complex128)
3.2.6 切片操作
3.2.6.1 func MakeSlice(typ Type, len, cap int) Value
功能:创建切片 Value
参数:
typ Type:切片元素类型len int:切片长度cap int:切片容量
返回值:切片 Value
注意事项:
返回的切片可设置
容量不能小于长度
3.2.6.2 Append(s Value, x ...Value) Value
功能:向切片追加元素 参数:
s Value:目标切片x ...Value:要追加的元素
返回值:新切片 Value
注意事项:
原始切片不会被修改
返回新切片需重新赋值
3.2.6.3 AppendSlice(s, t Value) Value
功能:向切片追加另一个切片 参数:
s Value:目标切片t Value:要追加的切片
返回值:新切片 Value
注意事项:
两个切片元素类型必须相同
方法名
功能描述
参数说明
返回值
注意事项
Append(s Value, x ...Value)
追加元素
s: 切片, x: 元素
Value
返回新切片
AppendSlice(s, t Value)
追加切片
s: 目标, t: 源
Value
元素类型必须相同
Cap()
获取容量
无
int
适用于切片/数组/通道
Len()
获取长度
无
int
适用于容器类型
Index(i int)
获取元素
i: 索引
Value
Slice(i, j int)
切片操作
i,j: 起止索引
Value
Slice3(i, j, k int)
带容量切片
i,j,k: 索引
Value
SetLen(n int)
设置长度
n: 新长度
无
必须可设置
SetCap(n int)
设置容量
n: 新容量
无
必须可设置
Grow(n int)
增加容量
n: 增加量
无
Go 1.20+
Clear()
清空容器
无
无
切片设长度0,映射清空
3.2.7 映射操作
3.2.7.1 func MakeMap(typ Type) Value
功能:创建映射 Value
参数:typ Type - 映射类型
返回值:映射 Value
注意事项:
键类型必须可比较
返回的映射可设置
3.2.7.2 SetMapIndex(key, elem Value)
功能:设置映射键值对 参数:
key Value:键elem Value:值
注意事项:
映射必须可设置
键类型必须匹配
3.2.7.3 MapIndex(key Value) Value
功能:获取映射值
返回值:值 Value(无效值表示键不存在)
方法名
功能描述
参数说明
返回值
注意事项
MapIndex(key Value)
获取键值
key: 键
Value
无效值表示键不存在
MapKeys()
获取所有键
无
[]Value
MapRange()
获取迭代器
无
*MapIter
SetMapIndex(key, elem Value)
设置键值
key: 键, elem: 值
无
SetIterKey(iter *MapIter)
设置迭代器键
iter: 迭代器
无
SetIterValue(iter *MapIter)
设置迭代器值
iter: 迭代器
无
3.2.8 通道操作
3.2.8.1 func MakeChan(typ Type, buffer int) Value
功能:创建通道 Value
参数:
typ Type:通道元素类型buffer int:缓冲区大小
返回值:通道 Value
注意事项:
返回的通道可操作
缓冲区大小 >= 0
3.2.8.2 Send(x Value)
功能:向通道发送值 注意事项:
通道必须可发送
值类型必须匹配
3.2.8.3 Recv() (Value, bool)
功能:从通道接收值 返回值:
Value:接收的值bool:是否成功接收
方法名
功能描述
参数说明
返回值
注意事项
Send(x Value)
发送值
x: 发送值
无
通道必须可发送
Recv()
接收值
无
(Value, bool)
TryRecv()
尝试接收
无
(Value, bool)
非阻塞
TrySend(x Value)
尝试发送
x: 发送值
bool
非阻塞
Close()
关闭通道
无
无
3.2.9 结构体操作
3.2.9.1 Field(i int) Value
功能:获取结构体字段值 注意事项:
仅适用于结构体类型
索引从 0 开始
3.2.9.2 FieldByName(name string) Value
功能:按名称获取字段值
返回值:字段值 Value(无效值表示字段不存在)
方法名
功能描述
参数说明
返回值
注意事项
Field(i int)
获取字段
i: 字段索引
Value
FieldByIndex(index []int)
嵌套字段访问
index: 索引路径
Value
FieldByIndexErr(index []int)
嵌套字段访问(带错误)
index: 索引路径
(Value, error)
FieldByName(name string)
按名称获取字段
name: 字段名
Value
FieldByNameFunc(match func(string) bool)
函数匹配字段
match: 匹配函数
Value
NumField()
字段数量
无
int
3.2.10 函数调用方法
3.2.10.1 Call(in []Value) []Value
功能:调用函数
参数:in []Value - 参数列表
返回值:返回值列表
注意事项:
函数必须为
Func类型参数数量和类型必须匹配
3.2.10.2 CallSlice(in []Value) []Value
功能:调用可变参数函数
参数:in []Value - 参数列表
返回值:返回值列表
注意事项:
最后一个参数必须是切片
相当于展开切片作为可变参数
方法名
功能描述
参数说明
返回值
注意事项
Call(in []Value)
调用函数
in: 参数列表
[]Value
参数必须匹配
CallSlice(in []Value)
调用可变函数
in: 参数列表
[]Value
最后参数为切片
NumMethod()
方法数量
无
int
Method(i int)
获取方法
i: 方法索引
Value
MethodByName(name string)
按名称获取方法
name: 方法名
Value
3.2.11 指针操作
方法名
功能描述
参数说明
返回值
注意事项
Elem()
解引用
无
Value
适用于指针/接口
Pointer()
获取指针值
无
uintptr
UnsafeAddr()
获取地址
无
uintptr
值必须可寻址
UnsafePointer()
获取 unsafe.Pointer
无
unsafe.Pointer
SetPointer(x unsafe.Pointer)
设置指针
x: 新指针
无
Indirect(v Value)
解引用指针
v: 值
Value
非指针返回原值
3.2.12 类型检查与转换
3.2.12.1 CanConvert(t Type) bool
功能:检查值是否可转换为目标类型 返回值:是否可转换
3.2.12.2 Convert(t Type) Value
功能:转换值到目标类型
返回值:转换后的 Value
注意事项:
转换可能丢失精度
必须
CanConvert返回true
方法名
功能描述
参数说明
返回值
注意事项
Kind()
获取底层类型
无
Kind
优先使用此方法
Type()
获取类型信息
无
Type
CanAddr()
是否可寻址
无
bool
CanSet()
是否可设置
无
bool
CanConvert(t Type)
是否可转换
t: 目标类型
bool
IsNil()
是否为 nil
无
bool
适用于指针/接口等
IsValid()
是否有效
无
bool
零值 Value 无效
IsZero()
是否零值
无
bool
Comparable()
是否可比较
无
bool
3.2.13 特殊操作
3.2.13.1 Indirect(v Value) Value
功能:获取指针指向的值 等价于:
如果
v是指针:v.Elem()否则:
v
3.2.13.2 SetZero()
功能:将值设为零值 注意事项:
值必须可设置
相当于
v.Set(reflect.Zero(v.Type()))
3.2.13.3 Select(cases []SelectCase) (chosen int, recv Value, recvOK bool)
功能说明
动态模拟 select 语句,在多个通道操作中选择一个就绪的操作执行。
参数说明
cases []SelectCase:选择分支列表Dir SelectDir:操作方向(SelectSend、SelectRecv、SelectDefault)Chan Value:通道值Send Value:发送值(仅SelectSend时使用)
返回值
chosen int:选中的分支索引recv Value:接收的值(仅接收操作)recvOK bool:接收是否成功
使用场景
动态处理多个通道
实现通用通道选择器
构建事件驱动系统
3.2.13.4 Seq() iter.Seq[Value] (Go 1.22+)
功能说明
返回值的迭代序列(实现 iter.Seq[Value])
支持类型
数组
切片
字符串
映射(迭代键)
通道(接收值)
使用场景
统一迭代接口
简化反射迭代代码
与 Go 1.22 迭代器函数集成
方法名
功能描述
参数说明
返回值
注意事项
Select(cases []SelectCase)
多路选择
cases: 选择分支
(int, Value, bool)
模拟 select
Equal(u Value)
深度比较
u: 比较值
bool
递归比较
Seq()
迭代序列
无
iter.Seq[Value]
Go 1.22+
Seq2()
键值迭代
无
iter.Seq2[Value, Value]
Go 1.22+ 仅限映射
3.2.14 数值检查
方法名
功能描述
参数说明
返回值
注意事项
OverflowInt(x int64)
检查整数溢出
x: 测试值
bool
OverflowUint(x uint64)
检查无符号溢出
x: 测试值
bool
OverflowFloat(x float64)
检查浮点溢出
x: 测试值
bool
OverflowComplex(x complex128)
检查复数溢出
x: 测试值
bool
3.3 Kind类型
reflect.Kind 是 Go 反射系统中表示类型基础种类的枚举类型,它是理解和使用反射的基础。
Kind 表示 Go 类型系统的基本分类,它标识了类型的底层表示形式。与 reflect.Type 不同,Kind 不区分自定义类型和内置类型,只关注基础种类。
3.3.1 func (k Kind) String() string
功能:返回种类的字符串表示 返回值:种类名称(如 "int"、"slice" 等) 注意事项:
用于调试和日志输出
比直接使用整数更易读
核心用途
类型基础判断:快速确定值的底层表示形式
类型安全操作:在调用类型特定方法前进行验证
性能优化:比完整类型检查更高效
泛型处理:在泛型代码中处理不同类型的基础操作
3.4 StructField 类型
StructField 描述结构体中的单个字段,包含字段的元数据信息。
核心用途
获取结构体字段信息
解析字段标签
处理嵌套结构
动态访问字段值
3.4.1 func VisibleFields(t Type) []StructField (Go 1.17+)
功能说明
获取结构体所有可见字段(包括嵌入字段的字段)
参数说明
t Type:结构体类型
返回值
[]StructField:所有可见字段
核心用途
处理包含嵌入字段的结构体
注意事项
字段顺序:按字段在内存中的布局排序
包含未导出字段:但无法直接访问值
嵌入字段展开:将嵌入字段的字段提升到外层
3.4.2 func (f StructField) IsExported() bool (Go 1.17+)
功能说明
检查字段是否为导出字段(首字母大写)
返回值
bool:是否导出
使用场景
安全地处理可能包含未导出字段的结构体
3.5 StructTag 类型
表示结构体字段的标签字符串(反引号内的内容)
解析字段标签(如 JSON、XML、数据库ORM标签)
3.5.1 func (tag StructTag) Get(key string) string
功能:获取标签值
参数:key string - 标签键
返回值:标签值(不存在时返回空字符串)
注意事项:
不区分大小写
只返回第一个匹配值
支持逗号分隔的多个值
3.5.2 func (tag StructTag) Lookup(key string) (value string, ok bool)
功能:检查并获取标签值
参数:key string - 标签键
返回值:
value string:标签值ok bool:是否存在 注意事项:区分大小写(Go 1.14+)
可以明确区分空值和不存在
3.6 MapIter 类型
reflect.MapIter 是 Go 反射系统中用于安全、高效遍历映射的迭代器类型。它提供了比 MapKeys() 更高效的内存使用方式,特别适合处理大型映射。
MapIter 是一个映射迭代器,用于遍历映射的键值对。它通过避免一次性分配所有键值对,显著降低了大型映射遍历时的内存开销。
3.6.1.1 func (iter *MapIter) Key() Value
功能:返回当前键的 Value
返回值:键的反射值
注意事项:
必须在
Next()返回true后调用返回的值在迭代期间有效
3.6.1.2 func (iter *MapIter) Value() Value
功能:返回当前值的 Value
返回值:值的反射值
注意事项:
必须在
Next()返回true后调用返回的值在迭代期间有效
3.6.1.3 func (iter *MapIter) Next() bool
功能:推进到下一个键值对 返回值:
true:还有下一个键值对false:迭代结束
注意事项:
首次调用前迭代器未定位
返回
false后不应再调用Key()或Value()
3.6.1.4 func (iter *MapIter) Reset(v Value)
功能:重置迭代器以遍历新映射
参数:v Value - 新的映射值
注意事项:
v必须是映射类型重置后需重新调用
Next()开始迭代
3.7 SelectCase 类型
表示 select 的一个 case
使用场景:
动态构建 select 语句
实现基于反射的通道选择
关键点说明
操作方向:
SelectSend:向通道发送值SelectRecv:从通道接收值SelectDefault:默认操作(立即执行)
返回值:
chosen int:选中的 case 索引recv Value:接收的值(仅接收操作)recvOK bool:接收是否成功
错误处理:
向已关闭通道发送会 panic
从 nil 通道操作会永久阻塞
使用 recover 处理可能的 panic
性能考虑:
比原生 select 慢约 10 倍
适合动态构建 select 的场景
使用注意事项
通道状态:
关闭的通道接收会返回
recvOK = falsenil 通道会永久阻塞(除非有默认 case)
类型安全:
发送值类型必须匹配通道元素类型
使用前检查
Chan.IsValid()和Chan.Kind() == Chan
默认操作:
当没有其他 case 就绪时执行
没有
Chan和Send字段
重置使用:
可以重用
SelectCase切片修改
Chan为 nil 可禁用 case
3.8 SelectDir 类型
表示 select 操作的方向
使用场景:
定义
SelectCase的操作类型指示通道操作方向
最后更新于