乐趣区

关于golang:go语言中的反射

以前用 Java 开发的时候,尤其是接触到略微底层一点的货色,比方 AOP,动静代理这些货色,都要用到反射,当初学习 go 语言,发射这些反射和 Java 外面的及其相似,不过也有差别,以下是一些代码演示

根本数据类型的反射

package main
// 反射,根本数据类型
import (
    "fmt"
    "reflect"
)

type myInt int
type Person struct {
    Name string
    Age  int
}

func reflectType(v interface{}) {typeOf := reflect.TypeOf(v)
    name := typeOf.Name()
    kind := typeOf.Kind()
    fmt.Printf("【typeof】: %v,【Name】: %v,【Kind】: %v\n", typeOf, name, kind)
}
func reflectValue(v interface{}) {val := reflect.ValueOf(v)
    kind := val.Kind()
    fmt.Println("原始类型:", kind)
    switch kind {
    case reflect.Int:
        fmt.Println(val.Int())
    case reflect.String:

        fmt.Println(val.String())
    case reflect.Float32:
        fmt.Println(val.Float())
    default:
        fmt.Println("还没有去判断这个类型")
    }
}
func resetValue(v interface{}) {val := reflect.ValueOf(v)
    kind := val.Kind()
    // 如果传入的参数不是指针类型,那么就不能对其原始的变量进行赋值
    // 然而如果传入的参数是指针类型,通过 val.Kind() 办法获取到的是 ptr 类型
    // 如果想要判断是 int,则须要应用 val.Elem().Kind() 办法
    fmt.Println(kind)
    k := val.Elem().Kind()
    fmt.Println("理论类型:", k)
    if k == reflect.Int64 {val.Elem().SetInt(2323)
    } else if k == reflect.String {val.Elem().SetString("hello golang")
    } else {fmt.Println("临时没设置这种类型")
    }
}
func main() {
    a := 10
    b := 12.3
    c := true
    d := "nihao"
    var e myInt = 12
    f := Person{
        Name: "nihao",
        Age:  12,
    }
    g := [3]int{0, 1, 2}
    h := []int{4, 5}
    var i = &a

    reflectType(a)
    reflectType(b)
    reflectType(c)
    reflectType(d)
    reflectType(e)
    reflectType(f)
    reflectType(g)
    reflectType(h)
    reflectType(i)
    reflectValue(23)
    reflectValue("string")

    var aint = 12
    resetValue(&aint)
    fmt.Println(aint)

}

构造体的反射

package main

import (
    "fmt"
    "reflect"
)

// 反射,构造体

type Person struct {
    Name    string `json:"name"`
    Age     int    `json:"age"`
    Address string
}

func (p Person) GetInfo() string {return fmt.Sprintf("Name:%v,Age:%v,Address:%v", p.Name, p.Age, p.Address)
}
func (p *Person) SetInfo(name string, age int, address string) {
    p.Name = name
    p.Age = age
    p.Address = address
}
func main() {
    var p = Person{
        Name:    "silk",
        Age:     20,
        Address: "苏州",
    }
    t := reflect.TypeOf(p)
    if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct {fmt.Println("传入的类型不是构造体")
    }
    field := t.Field(0)
    fmt.Println(field.Name)
    fmt.Println(field.Type)
    fmt.Println(field.Tag.Get("json"))
    name, ok := t.FieldByName("Age")
    if ok {fmt.Println(name.Name)
        fmt.Println(name.Type)
        fmt.Println(name.Tag.Get("json"))
    }
    for i := 0; i < t.NumField(); i++ {fmt.Printf("name:%v,type:%v,tag:%v\n", t.Field(i).Name, t.Field(i).Type, t.Field(i).Tag.Get("json"))
    }

    method := t.NumMethod()
    fmt.Println("methodcount:", method)
    for i := 0; i < method; i++ {fmt.Println(t.Method(i).Name)
    }
    // 留神,当应用 SetInfo 办法时候,传入的必须是指针类型,否则会报错
    val := reflect.ValueOf(&p)
    call := val.MethodByName("GetInfo").Call(nil)
    fmt.Println(call)
    var params []reflect.Value
    params = append(params, reflect.ValueOf("java0904"))
    params = append(params, reflect.ValueOf(23))
    params = append(params, reflect.ValueOf("苏州市工业园区"))
    val.MethodByName("SetInfo").Call(params)
    call = val.MethodByName("GetInfo").Call(nil)
    fmt.Println(call)
    fmt.Println(p)

}

原文链接:https://www.sdk.cn/details/m1RMx6MZwxVWbYwWQo
SDK 社区是一个中立的社区,这里有多样的前端常识,有丰盛的 api,有爱学习的人工智能开发者,有有趣风趣的开发者带你学 python,还有将来炽热的鸿蒙,当各种元素组合在一起,让咱们一起脑洞大开独特打造业余、好玩、有价值的开发者社区,帮忙开发者实现自我价值!

退出移动版