go語言reflect理解

很多文章在講解GoLang的反射機制的時候都講的比較複雜,這裏簡單總結下,作一個淺顯的入門教程:this

一、TypeOf方法跟ValueOf方法spa

TypeOf用來返回變量的類型,ValueOf用來返回變量的方法。指針

咱們在初始化一個結構體的時候,有兩種方式,var a Struct跟a :=new(Struct),其中,前者的類型是struct,後者的類型是指針。code

package main

import (
	"fmt"
	"reflect"
)

type MyStruct struct {
	name string
}

func (this *MyStruct) GetName() string {
	return this.name
}

func main() {
	a := new(MyStruct)
	a.name = "yejianfeng"
	typ := reflect.TypeOf(a)
	fmt.Println(typ)
	fmt.Println("-------------------")
	var b MyStruct
	b.name = "abc"
	fmt.Println(reflect.TypeOf(b))
}

輸出以下:教程

*main.MyStructstring

-------------------入門

main.MyStructimport

二、reflect.ValueOf(a).FieldByName方法變量

若是a是結構體,reflect.ValueOf(a).FieldByName("name")等價於a.name。反射

若是是指針的話ValueOf返回的是指針的Type,它是沒有Field的,因此也就不能使用FieldByName

三、CanSet方法

CanSet當Value是可尋址的時候,返回true,不然返回false。

當前面的CanSet是一個指針的時候(p)它是不可尋址的,可是當是p.Elem()(實際上就是*p),它就是能夠尋址的

package main

import (
	"fmt"
	"reflect"
)

type MyStruct struct {
	name string
}

func (this *MyStruct) GetName() string {
	return this.name
}

func main() {
	var a MyStruct
	a.name = "xiangli"
	fmt.Println(reflect.ValueOf(a).FieldByName("name").CanSet()) //false
	fmt.Println(reflect.ValueOf(&(a.name)).Elem().CanSet())      //true

	fmt.Println("--------------")
	var c string = "yejianfeng"
	p := reflect.ValueOf(&c)
	fmt.Println(p.CanSet())        //false
	fmt.Println(p.Elem().CanSet()) //true
	p.Elem().SetString("newName")
	fmt.Println(c)
}

 

 

func main() {
	a := new(MyStruct)
	a.name = "yejianfeng"
	fmt.Println(reflect.TypeOf(a))
	fmt.Println(reflect.ValueOf(a))
	fmt.Println(reflect.ValueOf(a).Elem().Type())
	fmt.Println(reflect.TypeOf(a).Elem())
	fmt.Println("-------------------")
	var b MyStruct
	b.name = "abc"
	fmt.Println(reflect.TypeOf(b))
	fmt.Println(reflect.ValueOf(b))
}

返回值爲:

*main.MyStruct

&{yejianfeng}

main.MyStruct

main.MyStruct

-------------------

main.MyStruct

{abc}

相關文章
相關標籤/搜索