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:实际复制的元素数量

注意事项

  1. 目标和源必须都是切片或数组类型

  2. 目标和源的元素类型必须相同

  3. 如果目标是数组且不可设置(CanSet() == false),会引发 panic

  4. 特殊规则:当目标元素类型为 uint8 时,源可以是字符串(相当于 []byte 转换)

2.2 func DeepEqual(x, y any) bool

DeepEqual 递归比较两个值是否"深度(值)相等",比普通的 == 操作符更深入。它遵循以下规则:

比较规则

  1. ​数组​​:对应元素深度相等

  2. ​结构体​​:所有字段(包括未导出字段)深度相等

  3. ​函数​​:只有两者都为 nil 时才相等

  4. ​接口​​:持有的具体值深度相等

  5. ​映射​​:

    • 两者都为 nil 或都不为 nil

    • 长度相同

    • 相同键映射到深度相等的值

  6. ​指针​​:

    • 指针值相等(==)

    • 或指向深度相等的值

  7. ​切片​​:

    • 两者都为 nil 或都不为 nil

    • 长度相同

    • 指向相同底层数组或对应元素深度相等

    • ​注意​​:[]byte{}[]byte(nil) 不相等

  8. ​基本类型​​:使用 == 操作符比较

特殊情况

  • ​NaN 值​​:math.NaN() != math.NaN(),但包含 NaN 的指针相等

  • ​循环引用​​:检测到循环时认为指针相等

  • ​函数​​:非 nil 函数总是不相等(即使同一个函数)

2.3 func Swapper(slice any) func(i, j int)

Swapper 返回一个用于交换切片中元素的函数。该函数接收两个索引参数 ij,交换切片中这两个位置的元素。

参数说明

  • slice any:必须是切片类型

返回值

  • func(i, j int):交换函数,用于交换指定索引的元素

注意事项

  1. 如果传入的不是切片类型,会引发 panic

  2. 交换函数不检查索引是否越界(调用时需确保索引有效)

  3. 返回的函数会修改原始切片内容

2.4 最佳实践总结

2.4.1 reflect.Copy

  1. 优先使用内置的 copy() 函数(类型安全)

  2. 仅当处理 interface{} 类型时使用反射版本

  3. 注意目标容量限制,避免数据截断

  4. 特殊场景:字符串到 []byte 的转换

2.4.2 reflect.DeepEqual

  1. 测试中用于复杂结构的比较

  2. 注意未导出字段也会被比较

  3. 对于包含浮点数的结构,考虑自定义比较函数

  4. 性能敏感场景避免使用(递归比较开销大)

2.4.3 reflect.Swapper

  1. 实现排序算法时的便捷工具

  2. 比手动交换更简洁

  3. 注意只适用于切片,不适用于数组

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() == true

  • x 类型可赋值给 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:操作方向(SelectSendSelectRecvSelectDefault

    • 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" 等) ​​注意事项​​:

  • 用于调试和日志输出

  • 比直接使用整数更易读

核心用途

  1. ​类型基础判断​​:快速确定值的底层表示形式

  2. ​类型安全操作​​:在调用类型特定方法前进行验证

  3. ​性能优化​​:比完整类型检查更高效

  4. ​泛型处理​​:在泛型代码中处理不同类型的基础操作

3.4 StructField 类型

StructField 描述结构体中的单个字段,包含字段的元数据信息。

核心用途

  1. 获取结构体字段信息

  2. 解析字段标签

  3. 处理嵌套结构

  4. 动态访问字段值

3.4.1 func VisibleFields(t Type) []StructField (Go 1.17+)

功能说明

获取结构体所有可见字段(包括嵌入字段的字段)

参数说明

  • t Type:结构体类型

返回值

  • []StructField:所有可见字段

核心用途

处理包含嵌入字段的结构体

注意事项

  1. ​字段顺序​​:按字段在内存中的布局排序

  2. ​包含未导出字段​​:但无法直接访问值

  3. ​嵌入字段展开​​:将嵌入字段的字段提升到外层

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 语句

  • 实现基于反射的通道选择

关键点说明

  1. ​操作方向​​:

    • SelectSend:向通道发送值

    • SelectRecv:从通道接收值

    • SelectDefault:默认操作(立即执行)

  2. ​返回值​​:

    • chosen int:选中的 case 索引

    • recv Value:接收的值(仅接收操作)

    • recvOK bool:接收是否成功

  3. ​错误处理​​:

    • 向已关闭通道发送会 panic

    • 从 nil 通道操作会永久阻塞

    • 使用 recover 处理可能的 panic

  4. ​性能考虑​​:

    • 比原生 select 慢约 10 倍

    • 适合动态构建 select 的场景

使用注意事项

  1. ​通道状态​​:

    • 关闭的通道接收会返回 recvOK = false

    • nil 通道会永久阻塞(除非有默认 case)

  2. ​类型安全​​:

    • 发送值类型必须匹配通道元素类型

    • 使用前检查 Chan.IsValid()Chan.Kind() == Chan

  3. ​默认操作​​:

    • 当没有其他 case 就绪时执行

    • 没有 ChanSend 字段

  4. ​重置使用​​:

    • 可以重用 SelectCase 切片

    • 修改 Chan 为 nil 可禁用 case

3.8 SelectDir 类型

表示 select 操作的方向

使用场景​​:

  • 定义 SelectCase 的操作类型

  • 指示通道操作方向

最后更新于