Go reflect包
反射是由 reflect 包提供支持. 它定义了两个重要的类型, Type 和 Value. 一个 Type 表示一个Go类型. 函数 reflect.TypeOf 接受任意的 interface{} 类型, 并返回对应动态类型的reflect.Type.
reflect 包中另一个重要的类型是 Value. 一个 reflect.Value 可以持有一个任意类型的值. 函数 reflect.ValueOf 接受任意的 interface{} 类型, 并返回对应动态类型的reflect.Value. 和 reflect.TypeOf 类似, reflect.ValueOf 返回的结果也是对于具体的类型, 但是 reflect.Value 也可以持有一个接口值.
reflect.Type 类型
代码,
package main
import (
"fmt"
"reflect"
"unsafe"
)
// 嵌套结构体
type ss struct {
a struct {
int
string
}
int
string
bool
float64
}
func (s ss) Method1(i int) string { return "结构体方法1" }
func (s *ss) Method2(i int) string { return "结构体方法2" }
var (
intValue = int(0)
int8Value = int8(8)
int16Value = int16(16)
int32Value = int32(32)
int64Value = int64(64)
uIntValue = uint(0)
uInt8Value = uint8(8)
uInt16Value = uint16(16)
uInt32Value = uint32(32)
uInt64Value = uint64(64)
byteValue = byte(0)
runeValue = rune(0)
uintptrValue = uintptr(0)
boolValue = false
stringValue = ""
float32Value = float32(32)
float64Value = float64(64)
complex64Value = complex64(64)
complex128Value = complex128(128)
arrayValue = [5]string{} // 数组
sliceValue = []byte{0, 0, 0, 0, 0} // 切片
mapValue = map[string]int{} // 映射
chanValue = make(chan int, 2) // 通道
structValue = ss{ // 结构体
struct {
int
string
}{10, "子结构体"},
20,
"结构体",
false,
64.0,
}
func1Value = func(a, b, c int) string { // 函数(固定参数)
return fmt.Sprintf("固定参数:%v %v %v", a, b, c)
}
func2Value = func(a, b int, c ...int) string { // 函数(动态参数)
return fmt.Sprintf("动态参数:%v %v %v", a, b, c)
}
unsafePointer = unsafe.Pointer(&structValue) // 通用指针
reflectType = reflect.TypeOf(0) // 反射类型
reflectValue = reflect.ValueOf(0) // 反射值
reflectArrayValue = reflect.ValueOf([]int{1, 2, 3}) // 切片反射值
interfaceType = reflect.TypeOf(new(interface{})).Elem() // 反射接口类型
)
// 简单类型
var simpleTypes = []interface{}{
intValue, &intValue, // int
int8Value, &int8Value, // int8
int16Value, &int16Value, // int16
int32Value, &int32Value, // int32
int64Value, &int64Value, // int64
uIntValue, &uIntValue, // uint
uInt8Value, &uInt8Value, // uint8
uInt16Value, &uInt16Value, // uint16
uInt32Value, &uInt32Value, // uint32
uInt64Value, &uInt64Value, // uint64
byteValue, &byteValue, // byte
runeValue, &runeValue, // rune
uintptrValue, &uintptrValue, // uintptr
boolValue, &boolValue, // bool
stringValue, &stringValue, // string
float32Value, &float32Value, // float32
float64Value, &float64Value, // float64
complex64Value, &complex64Value, // complex64
complex128Value, &complex128Value, // complex128
}
// 复杂类型
var complexTypes = []interface{}{
arrayValue, &arrayValue, // 数组
sliceValue, &sliceValue, // 切片
mapValue, &mapValue, // 映射
chanValue, &chanValue, // 通道
structValue, &structValue, // 结构体
func1Value, &func1Value, // 定参函数
func2Value, &func2Value, // 动参函数
structValue.Method1, structValue.Method2, // 方法
unsafePointer, &unsafePointer, // 指针
reflectType, &reflectType, // 反射类型
reflectValue, &reflectValue, // 反射值
interfaceType, &interfaceType, // 接口反射类型
}
// 空值
var unsafeP unsafe.Pointer
// 空接口
var nilInterfece interface{}
func main() {
// 测试简单类型
for i := 0; i < len(simpleTypes); i++ {
PrintInfo(simpleTypes[i])
}
// 测试复杂类型
for i := 0; i < len(complexTypes); i++ {
PrintInfo(complexTypes[i])
}
// 测试单个对象
PrintInfo(unsafeP)
PrintInfo(&unsafeP)
PrintInfo(nilInterfece)
PrintInfo(&nilInterfece)
}
func PrintInfo(i interface{}) {
if i == nil {
fmt.Println("--------------------")
fmt.Printf("无效接口值:%v\n", i)
return
}
t := reflect.TypeOf(i)
PrintType(t)
}
func PrintType(t reflect.Type) {
fmt.Println("--------------------")
// ----- 通用方法 -----
fmt.Println("String :", t.String()) // 类型字符串
fmt.Println("Name :", t.Name()) // 类型名称
fmt.Println("PkgPath :", t.PkgPath()) // 所在包名称
fmt.Println("Kind :", t.Kind()) // 所属分类
fmt.Println("Size :", t.Size()) // 内存大小
fmt.Println("Align :", t.Align()) // 字节对齐
fmt.Println("FieldAlign :", t.FieldAlign()) // 字段对齐
fmt.Println("NumMethod :", t.NumMethod()) // 方法数量
if t.NumMethod() > 0 {
i := 0
for ; i < t.NumMethod()-1; i++ {
fmt.Println(" ┣", t.Method(i).Name) // 通过索引定位方法
}
fmt.Println(" ┗", t.Method(i).Name) // 通过索引定位方法
}
if sm, ok := t.MethodByName("String"); ok { // 通过名称定位方法
fmt.Println("MethodByName :", sm.Index, sm.Name)
}
fmt.Println("Implements(i{}) :", t.Implements(interfaceType)) // 是否实现了指定接口
fmt.Println("ConvertibleTo(int) :", t.ConvertibleTo(reflectType)) // 是否可转换为指定类型
fmt.Println("AssignableTo(int) :", t.AssignableTo(reflectType)) // 是否可赋值给指定类型的变量
fmt.Println("Comparable :", t.Comparable()) // 是否可进行比较操作
// ----- 特殊类型 -----
switch t.Kind() {
// 指针型:
case reflect.Ptr:
fmt.Println("=== 指针型 ===")
// 获取指针所指对象
t = t.Elem()
fmt.Printf("转换到指针所指对象 : %v\n", t.String())
// 递归处理指针所指对象
PrintType(t)
return
// 自由指针型:
case reflect.UnsafePointer:
fmt.Println("=== 自由指针 ===")
// ...
// 接口型:
case reflect.Interface:
fmt.Println("=== 接口型 ===")
// ...
}
// ----- 简单类型 -----
// 数值型:
if reflect.Int <= t.Kind() && t.Kind() <= reflect.Complex128 {
fmt.Println("=== 数值型 ===")
fmt.Println("Bits :", t.Bits()) // 位宽
}
// ----- 复杂类型 -----
switch t.Kind() {
// 数组型:
case reflect.Array:
fmt.Println("=== 数组型 ===")
fmt.Println("Len :", t.Len()) // 数组长度
fmt.Println("Elem :", t.Elem()) // 数组元素类型
// 切片型:
case reflect.Slice:
fmt.Println("=== 切片型 ===")
fmt.Println("Elem :", t.Elem()) // 切片元素类型
// 映射型:
case reflect.Map:
fmt.Println("=== 映射型 ===")
fmt.Println("Key :", t.Key()) // 映射键
fmt.Println("Elem :", t.Elem()) // 映射值类型
// 通道型:
case reflect.Chan:
fmt.Println("=== 通道型 ===")
fmt.Println("ChanDir :", t.ChanDir()) // 通道方向
fmt.Println("Elem :", t.Elem()) // 通道元素类型
// 结构体:
case reflect.Struct:
fmt.Println("=== 结构体 ===")
fmt.Println("NumField :", t.NumField()) // 字段数量
if t.NumField() > 0 {
var i, j int
// 遍历结构体字段
for i = 0; i < t.NumField()-1; i++ {
field := t.Field(i) // 获取结构体字段
fmt.Printf(" ├ %v\n", field.Name)
// 遍历嵌套结构体字段
if field.Type.Kind() == reflect.Struct && field.Type.NumField() > 0 {
for j = 0; j < field.Type.NumField()-1; j++ {
subfield := t.FieldByIndex([]int{i, j}) // 获取嵌套结构体字段
fmt.Printf(" │ ├ %v\n", subfield.Name)
}
subfield := t.FieldByIndex([]int{i, j}) // 获取嵌套结构体字段
fmt.Printf(" │ └ %%v\n", subfield.Name)
}
}
field := t.Field(i) // 获取结构体字段
fmt.Printf(" └ %v\n", field.Name)
// 通过名称查找字段
if field, ok := t.FieldByName("ptr"); ok {
fmt.Println("FieldByName(ptr) :", field.Name)
}
// 通过函数查找字段
if field, ok := t.FieldByNameFunc(func(s string) bool { return len(s) > 3 }); ok {
fmt.Println("FieldByNameFunc :", field.Name)
}
}
// 函数型:
case reflect.Func:
fmt.Println("=== 函数型 ===")
fmt.Println("IsVariadic :", t.IsVariadic()) // 是否具有变长参数
fmt.Println("NumIn :", t.NumIn()) // 参数数量
if t.NumIn() > 0 {
i := 0
for ; i < t.NumIn()-1; i++ {
fmt.Println(" ┣", t.In(i)) // 获取参数类型
}
fmt.Println(" ┗", t.In(i)) // 获取参数类型
}
fmt.Println("NumOut :", t.NumOut()) // 返回值数量
if t.NumOut() > 0 {
i := 0
for ; i < t.NumOut()-1; i++ {
fmt.Println(" ┣", t.Out(i)) // 获取返回值类型
}
fmt.Println(" ┗", t.Out(i)) // 获取返回值类型
}
}
}
reflect.Value 类型
代码,
package main
import (
"fmt"
"reflect"
"unsafe"
)
// 嵌套结构体
type ss struct {
a struct {
int
string
}
int
string
bool
float64
}
func (s ss) Method1(i int) string { return "结构体方法1" }
func (s *ss) Method2(i int) string { return "结构体方法2" }
var (
intValue = int(0)
int8Value = int8(8)
int16Value = int16(16)
int32Value = int32(32)
int64Value = int64(64)
uIntValue = uint(0)
uInt8Value = uint8(8)
uInt16Value = uint16(16)
uInt32Value = uint32(32)
uInt64Value = uint64(64)
byteValue = byte(0)
runeValue = rune(0)
uintptrValue = uintptr(0)
boolValue = false
stringValue = "stringValue"
float32Value = float32(32)
float64Value = float64(64)
complex64Value = complex64(64)
complex128Value = complex128(128)
arrayValue = [5]string{} // 数组
sliceValue = []byte{0, 0, 0, 0, 0} // 切片
mapValue = map[string]int{} // 映射
chanValue = make(chan int, 2) // 通道
structValue = ss{ // 结构体
struct {
int
string
}{10, "子结构体"},
20,
"结构体",
false,
64.0,
}
func1Value = func(i int) string { // 函数(固定参数)
return fmt.Sprintf("固定参数:%v", i)
}
func2Value = func(i ...int) string { // 函数(动态参数)
return fmt.Sprintf("动态参数:%v", i)
}
unsafePointer = unsafe.Pointer(&structValue) // 通用指针
reflectType = reflect.TypeOf(0) // 反射类型
reflectValue = reflect.ValueOf(0) // 反射值
reflectArrayValue = reflect.ValueOf([]int{1, 2, 3}) // 切片反射值
// 反射接口类型
interfaceType = reflect.TypeOf(new(interface{})).Elem()
)
// 简单类型
var simpleTypes = []interface{}{
intValue, &intValue, // int
int8Value, &int8Value, // int8
int16Value, &int16Value, // int16
int32Value, &int32Value, // int32
int64Value, &int64Value, // int64
uIntValue, &uIntValue, // uint
uInt8Value, &uInt8Value, // uint8
uInt16Value, &uInt16Value, // uint16
uInt32Value, &uInt32Value, // uint32
uInt64Value, &uInt64Value, // uint64
byteValue, &byteValue, // byte
runeValue, &runeValue, // rune
uintptrValue, &uintptrValue, // uintptr
boolValue, &boolValue, // bool
stringValue, &stringValue, // string
float32Value, &float32Value, // float32
float64Value, &float64Value, // float64
complex64Value, &complex64Value, // complex64
complex128Value, &complex128Value, // complex128
}
// 复杂类型
var complexTypes = []interface{}{
arrayValue, &arrayValue, // 数组
sliceValue, &sliceValue, // 切片
mapValue, &mapValue, // 映射
chanValue, &chanValue, // 通道
structValue, &structValue, // 结构体
func1Value, &func1Value, // 定参函数
func2Value, &func2Value, // 动参函数
structValue.Method1, structValue.Method2, // 方法
unsafePointer, &unsafePointer, // 指针
reflectType, &reflectType, // 反射类型
reflectValue, &reflectValue, // 反射值
interfaceType, &interfaceType, // 接口反射类型
}
// 空值
var unsafeP unsafe.Pointer
// 空接口
var nilInterfece interface{}
func main() {
// 测试简单类型
for i := 0; i < len(simpleTypes); i++ {
PrintInfo(simpleTypes[i])
}
// 测试复杂类型
for i := 0; i < len(complexTypes); i++ {
PrintInfo(complexTypes[i])
}
// 测试单个对象
PrintInfo(&unsafeP)
PrintInfo(nilInterfece)
// PrintInfo(&nilInterfece) // 会引发 panic
}
func PrintInfo(i interface{}) {
if i == nil {
fmt.Println("--------------------")
fmt.Printf("无效接口值:%v\n", i)
fmt.Println("--------------------")
return
}
v := reflect.ValueOf(i)
PrintValue(v)
}
func PrintValue(v reflect.Value) {
fmt.Println("--------------------")
// ----- 通用方法 -----
fmt.Println("String :", v.String()) // 反射值的字符串形式
fmt.Println("Type :", v.Type()) // 反射值的类型
fmt.Println("Kind :", v.Kind()) // 反射值的类别
fmt.Println("CanAddr :", v.CanAddr()) // 是否可以获取地址
fmt.Println("CanSet :", v.CanSet()) // 是否可以修改
if v.CanAddr() {
fmt.Println("Addr :", v.Addr()) // 获取地址
fmt.Println("UnsafeAddr :", v.UnsafeAddr()) // 获取自由地址
}
// 是否可转换为接口对象
fmt.Println("CanInterface :", v.CanInterface())
if v.CanInterface() {
fmt.Println("Interface :", v.Interface()) // 转换为接口对象
}
// 获取方法数量
fmt.Println("NumMethod :", v.NumMethod())
if v.NumMethod() > 0 {
// 遍历方法
i := 0
for ; i < v.NumMethod()-1; i++ {
fmt.Printf(" ┣ %v\n", v.Method(i).String())
// if i >= 4 { // 只列举 5 个
// fmt.Println(" ┗ ...")
// break
// }
}
fmt.Printf(" ┗ %v\n", v.Method(i).String())
// 通过名称获取方法
fmt.Println("MethodByName :", v.MethodByName("String").String())
}
// ----- 可获取指针的类型 -----
switch v.Kind() {
case reflect.Slice, reflect.Map, reflect.Chan, reflect.Func,
reflect.Ptr, reflect.UnsafePointer:
fmt.Println("Pointer :", v.Pointer())
}
// ----- 特殊类型 -----
switch v.Kind() {
// 指针:
case reflect.Ptr:
fmt.Println("=== 指针 ===")
// 获取指针地址
if !v.IsNil() {
// 获取指针所指对象
v = v.Elem() // 只有指针和接口类型可以使用 Elem()
fmt.Printf("转换到指针所指对象 : %v\n", v.Type())
// 递归处理指针所指对象
PrintValue(v)
return
}
// 自由指针:
case reflect.UnsafePointer:
fmt.Println("=== 自由指针 ===")
if v.Pointer() == 0 {
v.SetPointer(unsafePointer)
fmt.Println("重新指向新对象 :", v.Pointer())
}
// 将自由指针转换为 *ss 指针(因为定义 unsafePointer 时已经确定了类型)
s := (*ss)(v.Interface().(unsafe.Pointer))
// 获取反射值
v = reflect.ValueOf(s)
if !v.IsNil() {
// 获取指针所指对象
v = v.Elem() // 只有指针和接口类型可以使用 Elem()
fmt.Printf("转换到指针所指对象 : %v\n", v.Type())
// 递归处理指针所指对象
PrintValue(v)
return
}
// 接口:
case reflect.Interface:
fmt.Println("=== 接口 ===")
// 获取接口数据
fmt.Println("InterfaceData :", v.InterfaceData())
// 获取接口所包含的对象
v = v.Elem() // 只有指针和接口类型可以使用 Elem()
fmt.Printf("转换到接口所含对象 : %v\n", v.Type())
// 递归处理接口的动态对象
PrintValue(v)
return
}
// ----- 简单类型 -----
// 有符号整型:
if reflect.Int <= v.Kind() && v.Kind() <= reflect.Int64 {
fmt.Println("=== 有符号整型 ===")
fmt.Println("Int :", v.Int()) // 获取值
if v.CanSet() {
v.SetInt(10) // 设置值
fmt.Println("Int :", v.Int()) // 获取值
v.Set(reflect.ValueOf(20).Convert(v.Type())) // 设置值
}
fmt.Println("Int :", v.Int()) // 获取值
fmt.Println("OverflowInt :", v.OverflowInt(10)) // 是否溢出
}
// 无符号整型:
if reflect.Uint <= v.Kind() && v.Kind() <= reflect.Uint64 {
fmt.Println("=== 无符号整型 ===")
fmt.Println("Uint :", v.Uint()) // 获取值
if v.CanSet() {
v.SetUint(10) // 设置值
fmt.Println("Uint :", v.Uint()) // 获取值
v.Set(reflect.ValueOf(20).Convert(v.Type())) // 设置值
}
fmt.Println("Uint :", v.Uint()) // 获取值
fmt.Println("OverflowUint :", v.OverflowUint(10)) // 是否溢出
}
switch v.Kind() {
// 浮点数:
case reflect.Float32, reflect.Float64:
fmt.Println("=== 浮点数 ===")
fmt.Println("Float :", v.Float()) // 获取值
if v.CanSet() {
v.SetFloat(10) // 设置值
fmt.Println("Float :", v.Float()) // 获取值
v.Set(reflect.ValueOf(20).Convert(v.Type())) // 设置值
}
fmt.Println("Float :", v.Float()) // 获取值
fmt.Println("OverflowFloat :", v.OverflowFloat(10)) // 是否溢出
// 复数:
case reflect.Complex64, reflect.Complex128:
fmt.Println("=== 复数 ===")
fmt.Println("Complex :", v.Complex()) // 获取值
if v.CanSet() {
v.SetComplex(10) // 设置值
fmt.Println("Complex :", v.Complex()) // 获取值
v.Set(reflect.ValueOf(20 + 20i).Convert(v.Type())) // 设置值
}
fmt.Println("Complex :", v.Complex()) // 获取值
fmt.Println("OverflowComplex :", v.OverflowComplex(10)) // 是否溢出
// 布尔型:
case reflect.Bool:
fmt.Println("=== 布尔型 ===")
fmt.Println("Bool :", v.Bool()) // 获取值
if v.CanSet() {
v.SetBool(true) // 设置值
fmt.Println("Bool :", v.Bool()) // 获取值
v.Set(reflect.ValueOf(false)) // 设置值
}
fmt.Println("Bool :", v.Bool()) // 获取值
// 字符串:
case reflect.String:
fmt.Println("=== 字符串 ===")
fmt.Println("String :", v.String()) // 获取值
if v.CanSet() {
v.SetString("abc") // 设置值
fmt.Println("String :", v.String()) // 获取值
v.Set(reflect.ValueOf("def")) // 设置值
}
fmt.Println("String :", v.String()) // 获取值
// ----- 复杂类型 -----
// 切片型:
case reflect.Slice:
fmt.Println("=== 切片型 ===")
fmt.Println("Len :", v.Len()) // 获取长度
fmt.Println("Cap :", v.Cap()) // 获取容量
if v.CanSet() {
v.SetLen(4) // 不能大于 cap
v.SetCap(4) // 不能小于 len,只能缩,不能扩
fmt.Println("SetLen, SetCap :", v.Len(), v.Cap())
// 重新指定字节内容
if v.Type().Elem().Kind() == reflect.Uint8 {
v.SetBytes([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0})
}
fmt.Println("SetByte :", []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0})
}
// 获取字节内容
if v.Type().Elem().Kind() == reflect.Uint8 {
fmt.Println("Bytes :", v.Bytes())
}
// 根据索引获取元素
if v.Len() > 0 {
for i := 0; i < v.Len(); i++ {
fmt.Println("Index :", v.Index(i))
}
}
// 获取一个指定范围的切片
// 参数:起始下标,结束下标
// 长度 = 结束下标 - 起始下标
s1 := v.Slice(1, 2)
fmt.Println("Slice :", s1)
fmt.Println("Len :", s1.Len()) // 获取长度
fmt.Println("Cap :", s1.Cap()) // 获取容量
// 获取一个指定范围和容量的切片
// 参数:起始下标,结束下标,容量下标
// 长度 = 结束下标 - 起始下标
// 容量 = 容量下标 - 起始下标
s2 := v.Slice3(1, 2, 4)
fmt.Println("Slice :", s2)
fmt.Println("Len :", s2.Len()) // 获取长度
fmt.Println("Cap :", s2.Cap()) // 获取容量
// 映射型:
case reflect.Map:
fmt.Println("=== 映射型 ===")
// 设置键值,不需要检测 CanSet
v.SetMapIndex(reflect.ValueOf("a"), reflect.ValueOf(1))
v.SetMapIndex(reflect.ValueOf("b"), reflect.ValueOf(2))
v.SetMapIndex(reflect.ValueOf("c"), reflect.ValueOf(3))
// 获取键列表
fmt.Println("MapKeys :", v.MapKeys())
for _, idx := range v.MapKeys() {
// 根据键获取值
fmt.Println("MapIndex :", v.MapIndex(idx))
}
// 结构体:
case reflect.Struct:
fmt.Println("=== 结构体 ===")
// 获取字段个数
fmt.Println("NumField :", v.NumField())
if v.NumField() > 0 {
var i, j int
// 遍历结构体字段
for i = 0; i < v.NumField()-1; i++ {
field := v.Field(i) // 获取结构体字段
fmt.Printf(" ├ %-8v %v\n", field.Type(), field.String())
// 遍历嵌套结构体字段
if field.Kind() == reflect.Struct && field.NumField() > 0 {
for j = 0; j < field.NumField()-1; j++ {
subfield := v.FieldByIndex([]int{i, j}) // 获取嵌套结构体字段
fmt.Printf(" │ ├ %-8v %v\n", subfield.Type(), subfield.String())
// if i >= 4 { // 只列举 5 个
// fmt.Println(" ┗ ...")
// break
// }
}
subfield := v.FieldByIndex([]int{i, j}) // 获取嵌套结构体字段
fmt.Printf(" │ └ %-8v %v\n", subfield.Type(), subfield.String())
}
// if i >= 4 { // 只列举 5 个
// fmt.Println(" ┗ ...")
// break
// }
}
field := v.Field(i) // 获取结构体字段
fmt.Printf(" └ %-8v %v\n", field.Type(), field.String())
// 通过名称查找字段
if v := v.FieldByName("ptr"); v.IsValid() {
fmt.Println("FieldByName(ptr) :", v.Type().Name())
}
// 通过函数查找字段
v := v.FieldByNameFunc(func(s string) bool { return len(s) > 3 })
if v.IsValid() {
fmt.Println("FieldByNameFunc :", v.Type().Name())
}
}
// 通道型:
case reflect.Chan:
fmt.Println("=== 通道型 ===")
// 发送数据(会阻塞)
v.Send(reflectValue)
// 尝试发送数据(不会阻塞)
fmt.Println("TrySend :", v.TrySend(reflectValue))
// 接收数据(会阻塞)
if x, ok := v.Recv(); ok {
fmt.Println("Recv :", x) //
}
// 尝试接收数据(不会阻塞)
if x, ok := v.TryRecv(); ok {
fmt.Println("TryRecv :", x) //
}
// 因为要执行两次,通道和通道指针各执行一次,关闭后第二次就无法执行了。
// v.Close()
// 函数型:
case reflect.Func:
fmt.Println("=== 函数型 ===")
// 判断函数是否具有变长参数
if v.Type().IsVariadic() {
// 与可变参数对应的实参必须是切片类型的反射值(reflectArrayValue)。
fmt.Println("CallSlice :", v.CallSlice([]reflect.Value{reflectArrayValue})) //
// 也可以用 v.Call 调用变长参数的函数,只需传入 reflectValue 即可。
} else {
// 根据函数定义的参数数量,传入相应数量的反射值(reflectValue)。
fmt.Println("Call :", v.Call([]reflect.Value{reflectValue})) //
}
}
}
====END====