首页 > 技术文章 > go反射

wangtaobiu 2022-03-18 12:03 原文

一.反射的概念

  Go语言提供了一种机制在运行时更新和检查变量的值,调用变量的方法和变量支持的内在操作,但是在编译时并不知道这些变量的具体类型, 这种机制被称为反射.Go语言中的反射是由 reflect 包提供支持的,它定义了两个重要的类型 Type 和 Value 任意接口值在反射中都可以理解为由 reflect.Type 和 reflect.Value 两部分组成,并且 reflect 包提供了 reflect.TypeOf 和 reflect.ValueOf 两个函数来获取任意对象的 Value 和 Type.

二.reflect包

  1.基本操作

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

var str = "hello"
var student Student
    • 获取变量类型: TypeOf() 
// TypeOf returns the reflection Type that represents the dynamic type of i
// If i is a nil interface value, TypeOf returns nil.

fmt.Println(reflect.TypeOf(str))         // string
fmt.Println(reflect.TypeOf(student))     // main.Student
    • 获取变量的值: ValueOf()
// ValueOf returns a new Value initialized to the concrete value
// stored in the interface i. ValueOf(nil) returns the zero Value.

fmt.Println(reflect.ValueOf(str))         // hello
fmt.Println(reflect.ValueOf(student))     // { 0} 由于未给变量student赋值,返回对应类型的零值
    • 获取变量的种类: Kind()

     首先要知道reflect包中都有哪些类型:

const (
	Invalid Kind = iota
	Bool
	Int
	Int8
	Int16
	Int32
	Int64
	Uint
	Uint8
	Uint16
	Uint32
	Uint64
	Uintptr
	Float32
	Float64
	Complex64
	Complex128
	Array
	Chan
	Func
	Interface
	Map
	Ptr   // 表示指针类型
	Slice
	String
	Struct
	UnsafePointer
)

     示例:

fmt.Println(reflect.TypeOf(str).Kind())         // string
fmt.Println(reflect.ValueOf(str).Kind())        // string
fmt.Println(reflect.TypeOf(student).Kind())     // struct
fmt.Println(reflect.ValueOf(student).Kind())    // structh
    • 获取结构体标签
structName, _ := reflect.TypeOf(&student).Elem().FieldByName("Name")
tagName := structName.Tag.Get("json")

fmt.Println(tagName)  // name  student结构体中Name对应的json标签为name

  2. 修改变量的值

type Student struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}
var str = "hello"
var student = Student{"Bob", 23}

// 使用Elem()方法必须使用指针或interface类型
// Elem returns the value that the interface v contains
// or that the pointer v points to.
// It panics if v's Kind is not Interface or Ptr.
// It returns the zero Value if v is nil.

reflect.ValueOf(&str).Elem().SetString("world")
reflect.ValueOf(&student).Elem().FieldByName("Name").SetString("Lily")
fmt.Println(str)     // world
fmt.Println(student) // {Lily 23}

 

推荐阅读