真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

理解golang反射(reflectioninGo)-創(chuàng)新互聯(lián)

反射(reflection)是指在運行時,動態(tài)獲取程序結(jié)構(gòu)信息(元信息)的一種能力,是靜態(tài)類型語言都支持的一種特性,如Java, golang等。這里主要詳細(xì)介紹golang reflection相關(guān)知識

成都創(chuàng)新互聯(lián)長期為上千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為平南企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、做網(wǎng)站,平南網(wǎng)站改版等技術(shù)服務(wù)。擁有10多年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
類型與接口(Types and interfaces)
type MyInt int

var i int
var j MyInt

i 為int類型,j為MyInt類型。雖然i,j底層類型均為int,但它們屬于不同類型,沒有轉(zhuǎn)換不能相互賦值。

接口類型 interface, 表示一系列方法集合,任意concrete (non-interface) value 只要實現(xiàn)了接口方法,便可賦值給interface

// Reader is the interface that wraps the basic Read method.
type Reader interface {
    Read(p []byte) (n int, err error)
}

// Writer is the interface that wraps the basic Write method.
type Writer interface {
    Write(p []byte) (n int, err error)
}

var r io.Reader
r = os.Stdin
r = bufio.NewReader(r)
r = new(bytes.Buffer)
// and so on

r變量的靜態(tài)類型為io.Reader,實際類型可能是File, Buffer類型

interface{} 特殊接口類型,沒有任何方法,因此任何類型都可賦值給它
The representation of an interface
var r io.Reader
r = new(bytes.Buffer)

r變量的具體類型是io.Reader,實際類型是bytes.Buffer,那么在運行時,golang是如何實現(xiàn)的呢?

一個interface類型的變量存儲了2個信息, 一個值,類型對 pair:

  • 賦給變量的值(concrete value)

  • 變量值的類型描述符(value's type descriptor)

var r io.Reader
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
    return nil, err
}
r = tty

接口類型r 的 pair是(tty*os.File)


當(dāng)然r變量的value tty不僅僅實現(xiàn)了io.Reader接口中的Read方法,還實現(xiàn)了io.Writer中的Write方法,因此可以進(jìn)行

類型斷言(type assertion),試圖將r 轉(zhuǎn)換為io.Writer


var w io.Writer
w = r.(io.Writer)

此時,接口變量w的pair 為 (tty*os.File),也就是說r,w 底層value是一樣的,可以通過不同的type來暴露不同的方法出來。

繼續(xù)討論

var empty interface{}
empty = w //此處不需要type assertion,因為任意類型都可以看作實現(xiàn)了empty interface的方法

接口變量empty的 pair 為 (tty*os.File)

Reflection
1. Reflection goes from interface value to reflection object.(接口類型---> 反射類型(reflect.Value,reflect.Type))

反射,可以獲取interface類型變量的具體信息(

golang 反射包為reflect

// ValueOf returns a new Value initialized to the concrete value
// stored in the interface i. ValueOf(nil) returns the zero Value.
func ValueOf(i interface{}) Value //獲取pair中的value

// TypeOf returns the reflection Type that represents the dynamic type of i.
// If i is a nil interface value, TypeOf returns nil.
func TypeOf(i interface{}) Type   //獲取pair中的concrete type

eg:


var r io.Reader
r = os.Stdin   //  : 
rValue := reflect.ValueOf(r)
rType  := reflect.TypeOf(r)
fmt.Println("value:", rValue)
fmt.Println("type :", rType)

輸出:
value: &{0xc04205a000} //指針
type : *os.File

var f float64
f = 1.234
fmt.Println("f value:",reflect.ValueOf(f))
fmt.Println("f type :",reflect.TypeOf(f))
輸出:
f value: 1.234
f type : float64
2. Reflection goes from reflection object to interface value. 反射類型(reflect.Value,reflect.Type) --> 接口類型
type User struct {
   Id   int
   Name string
   Age  int
}

func (u User) ReflectCallFunc() {
   fmt.Println("reflect learn")
}

user := User{1, "test", 13}
var i interface{}
i = user

uValue := reflect.ValueOf(i)
uType  := reflect.TypeOf(i)
fmt.Println("uValue: ",uValue)
fmt.Println(uValue.Interface()) //轉(zhuǎn)換為interface類型,unpack uValue.Interface().(User)
fmt.Println(uValue.Type())
fmt.Println("uValue,string: ",uType.String())
fmt.Println("uType: ",uType.Name())

for i := 0; i < uType.NumField(); i++ { //獲取field信息
   field := uType.Field(i)
   value := uValue.Field(i).Interface()
   fmt.Printf("%s: %v = %v\n", field.Name, field.Type, value)
}

for i := 0; i < uType.NumMethod(); i++ {// 獲取method信息
   method := uType.Method(i) 
   fmt.Printf("method[%d] = %s \n",i,method.Name)
}

fmt.Println(uValue.Kind())
fmt.Println(uType.Kind())

3. To modify a reflection object, the value must be settable. 通過反射修改變量
var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println("settability of v:", v.CanSet()) //print: settability of v: false
v.SetFloat(7.1) // Error: will panic.

不可修改的原因:we pass a copy of x to reflect.ValueOf, so the interface value created as the argument to reflect.ValueOf is a copy of x, not x itself

解決辦法,傳遞指針??!


var x float64 = 3.4
p := reflect.ValueOf(&x) // Note: take the address of x.
fmt.Println("type of p:", p.Type())
fmt.Println("settability of p:", p.CanSet())

print:
type of p: *float64
settability of p: false //why ? p不可set,p指向的內(nèi)容可set,p指向的內(nèi)容即*p,如何獲得p指向的內(nèi)容?

reflect.Value 的Elem方法,可以獲取value 指向的內(nèi)容


v := p.Elem()
fmt.Println("settability of v:", v.CanSet())//settability of v: true
v.SetFloat(7.1)
fmt.Println(v.Interface()) //7.1
fmt.Println(x)             //7.1

4. Structs 反射操作實例
type T struct {
   A int
   B string
}
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
   f := s.Field(i)
   fmt.Printf("%d:%v %s %s = %v\n", i, s.Kind(), typeOfT.Field(i).Name, f.Type(), f.Interface())
}

fmt.Println("canSet:",s.CanSet())
s.Field(0).SetInt(24)
s.Field(1).SetString("Sunset Strip")

fmt.Println("after change: ",s.Interface())
5. 通過reflect 來調(diào)用方法
type User struct {
   Id   int
   Name string
   Age  int
}

func (u User) ReflectCallFunc() {
   fmt.Println("reflect learn")
}


func (u User) FuncHasArgs(name string, age int) {
   fmt.Println("FuncHasArgs name: ", name, ", age:", age, "and origal User.Name:", u.Name)
}

func (u User) FuncNoArgs() {
   fmt.Println("FuncNoArgs")
}

user := User{1, "test", 13}
uValue := reflect.ValueOf(user)
uType  := reflect.TypeOf(user)


m1 := uValue.MethodByName("FuncHasArgs")
m2 := uValue.MethodByName("FuncNoArgs")
m ,b := uType.MethodByName("FuncNoArgs")
args := []reflect.Value{reflect.ValueOf("xiong"), reflect.ValueOf(30)}
m1.Call(args)

args = make([]reflect.Value,0)
m2.Call(args)

fmt.Println("m1:",m1)
fmt.Println("m2:",m2)
fmt.Printf("m:%#v,isfound:%v\n",m,b)
fmt.Println(m1)

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


網(wǎng)站名稱:理解golang反射(reflectioninGo)-創(chuàng)新互聯(lián)
地址分享:http://weahome.cn/article/dcojss.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部