Go reflection(反射)

1. 反射的基本使用

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

import (
"fmt"
"reflect"
)

type User struct {
Id int
Name string
Age int
}

func (u User) Hello() {
fmt.Println("Hello, world")
}

func Info(o interface{}) {
t := reflect.TypeOf(o)
fmt.Println("type:", t.Name())
// print "type: User"

if k := t.Kind(); k != reflect.Struct {
fmt.Println("类型错误")
return
}

v := reflect.ValueOf(o)
fmt.Println("fields:")

for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
val := v.Field(i).Interface()
fmt.Printf("%6s: %v = %v\n", f.Name, f.Type, val)
}
// print
// fields:
// Id: int = 1
// Name: string = ok
// Age: int = 12

for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
fmt.Printf("%6s: %v\n", m.Name, m.Type)
}
// print "Hello: func(main.User)"
}

func main() {
u := User{1, "ok", 12}
Info(u)
}

注意:User 中的属性必须为大写程序才能正常运行,Go 是根据属性的首字母大小写来确定访问权限的,大写表示公有,小写表示私有。同理,方法签名 Hello 为小写,一样无法反射出对应的方法名。

2. 通过反射修改属性的值

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

import (
"fmt"
"reflect"
)

type User struct {
Id int
Name string
Age int
}

func main() {
u := User{1, "ok", 12}
Set(&u)
fmt.Println(u)
}

func Set(o interface{}) {
v := reflect.ValueOf(o)

if v.Kind() == reflect.Ptr && v.Elem().CanSet() {
v = v.Elem()
} else {
return
}

f := v.FieldByName("Name")

if !f.IsValid() {
fmt.Println("Not found")
return
}
if f.Kind() == reflect.String {
f.SetString("BYE")
}

}

3. 通过反射动态调用方法

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

import (
"fmt"
"reflect"
)

type User struct {
Id int
Name string
Age int
}

func (u User) Hello(name string) {
fmt.Println("Hello", name, ", my name is", u.Name)
}

func main() {
u := User{1, "ok", 12}
v := reflect.ValueOf(u)
mv := v.MethodByName("Hello")

args := []reflect.Value{reflect.ValueOf("john")}
mv.Call(args)
//print "Hello john , my name is ok"
}
您的支持将鼓励我继续创作!
0%