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 类型

代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
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 类型

代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
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====