Go语言反射获取

幸运草 2020年4月20日21:28:16函数代码评论阅读模式

反射可以在运行时动态获取变量的相关信息。Go语言中reflect包实现了运行时反射,允许程序操作任意类型的对象。典型用法是用静态类型interface{}保存一个值,通过调用TypeOf获取其动态类型信息,该函数返回一个Type类型值。调用ValueOf函数返回一个Value类型值,该值代表运行时的数据。Zero接受一个Type类型参数并返回一个代表该类型零值的Value类型值。

反射获取常用函数和方法:

func TypeOf(i interface{}) Type

TypeOf返回接口中保存的值的类型,TypeOf(nil)会返回nil。

func ValueOf(i interface{}) Value

ValueOf返回一个初始化为i接口保管的具体值的Value,ValueOf(nil)返回Value零值。

func (t Type) Elem() Type

返回map类型的键的类型。如非映射类型将panic

func (t Type) Field(i int) StructField

返回索引序列指定的嵌套字段的类型,等价于用索引中每个值链式调用本方法,如非结构体将会panic

func (tag StructTag) Get(key string) string

Get方法返回标签字符串中键key对应的值。如果标签中没有该键,会返回""。如果标签不符合标准格式,Get的返回值是不确定的。

反射获取应用

一、反射获取基本类型

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var o string = "oldboy"

    // 返回值的类型
    t := reflect.TypeOf(o)
    fmt.Println("o type:", t)

    // 返回具体值的Value
    v := reflect.ValueOf(o)
    fmt.Println("o value:", v)
}

运行结果:

o type: string
o value: oldboy

二、反射获取结构体

package main

import (
    "fmt"
    "reflect"
)

type School struct {
    Name   string
    Course string
}

func main() {
    o := School{
        Name:   "oldboy",
        Course: "Golang",
    }

    t := reflect.TypeOf(o)
    fmt.Println("o type:", t)

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

运行结果:

o type: main.School
o value: {oldboy Golang}

三、反射获取结构体 Tag

1、获取结构体元素单一 Tag

package main

import (
    "fmt"
    "reflect"
)

type Student struct {
    Name   string `json:"stu_name"`
    Age    int    `json:"stu_age"`
    Course string
}

func getStructTag(i interface{}) {
    t := reflect.TypeOf(i)

    tag := t.Elem().Field(0).Tag.Get("json")
    fmt.Printf("Name Tag:%sn", tag)

    tag = t.Elem().Field(1).Tag.Get("json")
    fmt.Printf("Age Tag:%sn", tag)
}

func main() {
    stu := Student{
        Name:   "oldboy",
        Age:    18,
        Course: "Golang",
    }
    getStructTag(&stu)
}

运行结果:

Name Tag:stu_name
Age Tag:stu_age

2、获取结构体元素多个 Tag

package main

import (
    "fmt"
    "reflect"
)

func main() {
    type User struct {
        Name string `json:"user_name" xml:"UserName"`
    }
    u := User{
        Name: "oldboy",
    }
    f := reflect.TypeOf(u).Field(0)
    fmt.Println(f.Tag.Get("json"))
    fmt.Println(f.Tag.Get("xml"))
}

3、循环获取结构体 Tag

package main

import (
    "fmt"
    "reflect"
)

func main() {
    type User struct {
        Name   string "user name"
        Passwd string `user passsword`
    }
    u := &User{
        Name:   "oldboy",
        Passwd: "******",
    }
    s := reflect.TypeOf(u).Elem()
    for i := 0; i < s.NumField(); i++ {
        fmt.Println(s.Field(i).Tag)
    }
}

特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
幸运草
Go语言中的常量 函数代码

Go语言中的常量

1 概述 常量,一经定义不可更改的量。功能角度看,当出现不需要被更改的数据时,应该使用常量进行存储,例如圆周率。从语法的角度看,使用常量可以保证数据,在整个运行期间内,不会被更改。例如当前处理器的架构...
Go语言的接口 函数代码

Go语言的接口

Go语言-接口 在Go语言中,一个接口类型总是代表着某一种类型(即所有实现它的类型)的行为。一个接口类型的声明通常会包含关键字type、类型名称、关键字interface以及由花括号包裹的若干方法声明...
Go语言支持的正则语法 函数代码

Go语言支持的正则语法

1 字符 语法 说明 . 任意字符,在单行模式(s标志)下,也可以匹配换行 字符类 否定字符类 d Perl 字符类 D 否定 Perl 字符类 ASCII 字符类 否定 ASCII 字符类 pN U...
Go语言的包管理 函数代码

Go语言的包管理

1 概述 Go 语言的源码复用建立在包(package)基础之上。包通过 package, import, GOPATH 操作完成。 2 main包 Go 语言的入口 main() 函数所在的包(pa...

发表评论