go语言反射reflection

2019-05-13  本文已影响0人  运维技术栈

反射:可以在运行时动态获取变量的相关信息

go语言中通过reflect包操作反射

获取基本类型

reflect.TypeOf()  //获取变量的类型,返回reflect.Type类型 
reflect.ValueOf()  //获取变量的值,返回reflect.Value类型 
reflect.Value.Kind()  //获取变量的类别,返回一个常量 
reflect.Value.Interface()  //转换成interface{}类型

例子:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var a float64 = 3.14
    fmt.Println("type: ", reflect.TypeOf(a))
    b := reflect.ValueOf(a)
    fmt.Println("value: ", b)
    fmt.Println("type: ", b.Type())
    fmt.Println("kind: ", b.Kind())
    fmt.Println("value: ", b.Float())

    fmt.Println(b.Interface())
    fmt.Printf("value is %5.2e\n", b.Interface())
    c := b.Interface().(float64)
    fmt.Println(c)
}

输出结果:

type:  float64
value:  3.14
type:  float64
kind:  float64
value:  3.14
3.14
value is 3.14e+00
3.14

获取结构体

例子:

package main

import (
    "fmt"
    "reflect"
)

type Member struct {
    Name string
    Age  int
}

func testStruct(b interface{}) {
    t := reflect.TypeOf(b)
    fmt.Println("type: ", t)

    v := reflect.ValueOf(b)
    fmt.Println("value: ", v)

    k := v.Kind()
    fmt.Println("kind: ", k)

    iv := v.Interface()

    mem, ok := iv.(Member)
    if ok {
        fmt.Printf("%v %T\n", mem, mem)
    }
}

func main() {
    var a = Member{
        Name: "Musker",
        Age:  22,
    }
    testStruct(a)
}

输出结果:

type:  main.Member
value:  {Musker 22}
kind:  struct
{Musker 22} main.Member

Elem反射操作基本类型

用来获取指针指向的变量,相当于: var a *int;

例子

package main

import (
    "fmt"
    "reflect"
)

func testEm(a interface{}) {
    val := reflect.ValueOf(a)
    ve := val.Elem()
    ve.SetInt(100)
    b := ve.Int()

    fmt.Printf("get value interface{} %d\n", b)
    fmt.Printf("string val: %d\n", val.Elem().Int())
}

func main() {
    var a int = 1
    fmt.Println("before: ", a)
    testEm(&a)
    fmt.Println("after: ", a)
}

输出结果:

before:  1
get value interface{} 100
string val: 100
after:  100

反射调用结构体方法

例子:

package main

import (
    "fmt"
    "reflect"
)

type Student struct {
    Name  string
    Age   int
    Score float32
}

func (s Student) Print() {
    fmt.Println(s)
}

func (s Student) Set(name string, age int, score float32) {
    s.Name = name
    s.Age = age
    s.Score = score
}

func TestStruct(a interface{}) {
    val := reflect.ValueOf(a)
    kd := val.Kind()

    fmt.Println(val, kd)
    // 判断是否为struct
    if kd != reflect.Struct {
        fmt.Println("expect struct")
        return
    }

    // 获取字段数量
    fields := val.NumField()
    fmt.Printf("strut has %d field\n", fields)

    // 获取字段类型
    for i := 0; i < fields; i++ {
        fmt.Printf("%d %v\n", i, val.Field(i).Kind())
    }

    // 获取方法数量
    methods := val.NumMethod()
    fmt.Printf("struct has %d methods\n", methods)

    // 反射调用Print方法
    var params []reflect.Value
    // params为参数列表,此处为[]
    val.Method(0).Call(params)
}

func main() {
    var a Student = Student{
        Name:  "Musker",
        Age:   22,
        Score: 99.99,
    }
    TestStruct(a)
}

输出结果:

{Musker 22 99.99} struct
strut has 3 field
0 string
1 int
2 float32
struct has 2 methods
{Musker 22 99.99}

Elem反射操作结构体

例子:

package main

import (
    "fmt"
    "reflect"
)

type Student struct {
    Name  string
    Age   int
    Score float32
}

func (s Student) Print() {
    fmt.Println(s)
}

func TestStruct(a interface{}) {
    val := reflect.ValueOf(a)
    kd := val.Kind()

    fmt.Println(val, kd)
    if kd != reflect.Ptr && val.Elem().Kind() == reflect.Struct {
        fmt.Println("expect struct")
        return
    }

    // 获取字段数量
    fields := val.Elem().NumField()
    fmt.Printf("struct has %d field\n", fields)

    //获取字段类型
    for i := 0; i < fields; i++ {
        fmt.Printf("%d %v\n", i, val.Elem().Field(i).Kind())
    }

    // 获取方法数量
    methods := val.Elem().NumField()
    fmt.Printf("struct has %d methods\n", methods)

    // 反射调用Print方法
    var params []reflect.Value
    val.Elem().Method(0).Call(params)

}

func main() {
    var a Student = Student{
        Name:  "stu01",
        Age:   18,
        Score: 92.8,
    }
    TestStruct(&a)
}

输出结果:

&{stu01 18 92.8} ptr
struct has 3 field
0 string
1 int
2 float32
struct has 3 methods
{stu01 18 92.8}

Elem反射获取tag

例子:

package main

import (
    "fmt"
    "reflect"
)

type Student struct {
    Name  string `json:"stu_name"`
    Age   int
    Score float32
}

func TestStruct(a interface{}) {
    typ := reflect.TypeOf(a)

    tag := typ.Elem().Field(0).Tag.Get("json")
    fmt.Printf("tag: %s\n", tag)
}

func main() {
    var a Student = Student{
        Name:  "Musker",
        Age:   22,
        Score: 99.99,
    }
    TestStruct(&a)
}

输出结果:

tag: stu_name
上一篇下一篇

猜你喜欢

热点阅读