0%

Go反射

  • 反射
  • 反射解析结构体标签
  • 结构体标签与 json

    反射

  • reflect.TypeOf() 获取变量类型
  • reflect.ValueOf() 获取变量的值
  • inputType.Field(i) 获取域对象
  • inputValue.Field(i).Interface() 获取域对象的值
  • inputType.Method(i) 获取方法
    注意事项:
  • 反射只能获取公有的域对象和方法,且方法的绑定不是指针
    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
    package main

    import (
    "fmt"
    "reflect"
    )

    type User struct {
    Id int
    Name string
    Age int
    }

    func (this User) Call() {
    fmt.Println("user is called ..")
    fmt.Printf("%v\n", this)
    }

    func main() {
    user := User{1, "Aceld", 18}

    DoFiledAndMethod(user)
    }

    func DoFiledAndMethod(input interface{}) {
    //获取input的type
    inputType := reflect.TypeOf(input)
    fmt.Println("inputType is :", inputType.Name())

    //获取input的value
    inputValue := reflect.ValueOf(input)
    fmt.Println("inputValue is:", inputValue)

    //通过type 获取里面的字段
    //1. 获取interface的reflect.Type,通过Type得到NumField ,进行遍历
    //2. 得到每个field,数据类型
    //3. 通过filed有一个Interface()方法等到 对应的value
    for i := 0; i < inputType.NumField(); i++ {
    field := inputType.Field(i)
    value := inputValue.Field(i).Interface()

    fmt.Printf("%s: %v = %v\n", field.Name, field.Type, value)
    }

    //通过type 获取里面的方法,调用
    for i := 0; i < inputType.NumMethod(); i++ {
    m := inputType.Method(i)
    fmt.Printf("%s: %v\n", m.Name, m.Type)
    }

    }
    运行结果:
    反射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
package main

import (
"fmt"
"reflect"
)

type resume struct {
Name string `info:"name" doc:"我的名字"`
Sex string `info:"sex"`
}

func findTag(str interface{}) {
t := reflect.TypeOf(str).Elem()

for i := 0; i < t.NumField(); i++ {
taginfo := t.Field(i).Tag.Get("info")
tagdoc := t.Field(i).Tag.Get("doc")
fmt.Println("info: ", taginfo, " doc: ", tagdoc)
}
}

func main() {
var re resume

findTag(&re)

}

运行结果:
反射2


结构体标签与 json

json 编解码:

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

import (
"encoding/json"
"fmt"
)

type Movie struct {
Title string `json:"title"`
Year int `json:"year"`
Price int `json:"rmb"`
Actors []string `json:"actors"`
}

func main() {
movie := Movie{"喜剧之王", 2000, 10, []string{"xingye", "zhangbozhi"}}

//编码的过程 结构体---> json
jsonStr, err := json.Marshal(movie)
if err != nil {
fmt.Println("json marshal error", err)
return
}

fmt.Printf("jsonStr = %s\n", jsonStr)

//解码的过程 jsonstr ---> 结构体
//jsonStr = {"title":"喜剧之王","year":2000,"rmb":10,"actors":["xingye","zhangbozhi"]}
myMovie := Movie{}
err = json.Unmarshal(jsonStr, &myMovie)
if err != nil {
fmt.Println("json unmarshal error ", err)
return
}

fmt.Printf("%v\n", myMovie)
}

运行结果:
反射3