反射与网络

Catalogue
  1. 1. 反射基本操作
  2. 2. 反射获取结构体字段和方法调用
  3. 3. 反射设置结构体字段的值
  4. 4. 反射实现适配器
  5. 5. 参考资料

反射基本操作

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
package main

import (
"fmt"
"reflect"
)

func main() {

// 反射对基本类型操作
//var num int = 10
//testReflect01(num)

// 反射对结构体操作
//var stu = Student{
// Name: "fuyi",
// Age: 22,
//}
//testReflect02(stu)

var num int = 10
testReflect03(&num)
fmt.Printf("num: %v\n", num)
}

func testReflect01(i interface{}) {
rType := reflect.TypeOf(i)
fmt.Printf("rType : %v, %T\n", rType, rType)

rVal := reflect.ValueOf(i)
fmt.Printf("rVal : %v, %T\n", rVal, rVal)

// rVal转interface
iV := rVal.Interface()

// 通过断言转具体类型
n := iV.(int)
fmt.Println("n : ", n + 1)
}

type Student struct {
Name string
Age int
}

func testReflect02(i interface{}) {
rType := reflect.TypeOf(i)
fmt.Printf("rType : %v, %T\n", rType, rType)

rVal := reflect.ValueOf(i)
fmt.Printf("rVal : %v, %T\n", rVal, rVal)

fmt.Printf("kind: rType=%v, rVal=%v\n", rType.Kind(), rVal.Kind())

iV := rVal.Interface()
stu, ok := iV.(Student)
if ok {
fmt.Printf("stu: %v, %v, %v", stu, stu.Name, stu.Age)
}
}

func testReflect03(i interface{}) {
rVal := reflect.ValueOf(i)
rVal.Elem().SetInt(20)
}

反射获取结构体字段和方法调用

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
package main

import (
"reflect"
"fmt"
)

type Monster struct {
Name string `json:"name"`
Age int `json:"monster_age"`
Score float32
Sex string
}

func (m Monster) Print() {
fmt.Println("---start---")
fmt.Println(m)
fmt.Println("---end---")
}

func (m Monster) GetSum(n1, n2 int) int {
return n1 + n2
}

func (m Monster) SetVal(name string, age int, score float32, sex string) {
m.Name = name
m.Age = age
m.Score = score
m.Sex = sex
}

func TestReflect(i interface{}) {
rTyp := reflect.TypeOf(i)
rVal := reflect.ValueOf(i)
kd := rVal.Kind()
if kd != reflect.Struct {
fmt.Println("expect struct")
return
}
numField := rVal.NumField()
fmt.Printf("numField: %v\n", numField)

for j := 0; j < numField; j++ {
sf := rTyp.Field(j)
fmt.Printf("Field: index = %v, val = %v, type = %v, tag = %v\n", j, rVal.Field(j), sf.Name, sf.Tag)
}

numMethod := rVal.NumMethod()
fmt.Printf("numMethod: %v\n", numMethod)

// 该索引按ASCII排序,即调用Print方法
rVal.Method(1).Call(nil)

var params []reflect.Value;
params = append(params, reflect.ValueOf(10))
params = append(params, reflect.ValueOf(20))
result := rVal.Method(0).Call(params)
fmt.Printf("result: %v", result[0].Int())
}



func main() {
//m := Monster{
// Name: "Lizhuo",
// Age: 22,
// Score: 93.3,
// Sex: "man",
//}
//TestReflect(m)

}

反射设置结构体字段的值

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
package main

import (
"reflect"
"fmt"
)

type User struct {
Name string
Age int
}

func main() {
var (
user *User
rVal reflect.Value
)
user = &User{}
rVal = reflect.ValueOf(user)
rVal = rVal.Elem()

rVal.FieldByName("Name").SetString("fuyi")
rVal.FieldByName("Age").SetInt(88)

fmt.Printf("user: %v", user)
}

反射实现适配器

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
package main

import (
"reflect"
"fmt"
)

func call1(n1, n2 int) {
fmt.Printf("call1 params: %v,%v\n", n1,n2)
}

func call2(n1,n2 int, s1 string) {
fmt.Printf("call2 params: %v,%v, %v\n", n1,n2, s1)
}

func bridge(call interface{}, args ...interface{}) {
var rArgs []reflect.Value
for i := 0; i < len(args); i++ {
rArgs = append(rArgs, reflect.ValueOf(args[i]))
}
reflect.ValueOf(call).Call(rArgs)
}

func main() {

bridge(call1, 1, 2)
bridge(call2, 1, 2, "haha")
}

参考资料