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

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

go語(yǔ)言反射獲取參數(shù)名 go反射調(diào)用方法

go語(yǔ)言中的反射

import (

創(chuàng)新互聯(lián)建站主營(yíng)榆社網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,app軟件開(kāi)發(fā)公司,榆社h5微信小程序開(kāi)發(fā)搭建,榆社網(wǎng)站營(yíng)銷(xiāo)推廣歡迎榆社等地區(qū)企業(yè)咨詢(xún)

"fmt"

"reflect"

)

func reflecType(x interface{}){

v := reflect.TypeOf(x)

fmt.Println("type:%v\n", v)

fmt.Println("type name:%v , rtpe kind:%v \n", v.getName(), v.getType())

}

type Cat struct{}

//通過(guò)反射設(shè)置變量的值

func reflectSetValue1(x interface{}){

v := reflect.ValueOf(x)

if v.Kind() == reflect.Int64{

v.SetInt(200) //修改的是副本, reflect 包會(huì)引發(fā)panic

}

}

//通過(guò)反射設(shè)置變量的值

func reflectSetValue2(x interface{}){

v := reflect.ValueOf(x)

//反射中使用Elem()獲取指針對(duì)應(yīng)的值

if v.Elem().Kind() == reflect.Int64{

v.Elem().SetInt(200)

}

}

func main(){

var a float32 = 3.14

reflectType(a) //type name:float32 type kind:float32

var b int64 = 100

reflectType(b) // type name :int64 type kind :int64

var c = Cat{}

reflectType(c) // type name :Cat type kind :struct

reflectSetValue1(b)

fmt.Println(b) //依然為100

reflectSetValue2(b)

}

golang反射自定義tag

維基百科中反射的定義:在計(jì)算機(jī)科學(xué)中,反射是指計(jì)算機(jī)程序在運(yùn)行時(shí)(Run time)可以訪問(wèn)、檢測(cè)和修改它本身狀態(tài)或行為的一種能力。用比喻來(lái)說(shuō),反射就是程序在運(yùn)行的時(shí)候能夠“觀察”并且修改自己的行為。

golang reflect包實(shí)現(xiàn)了反射。動(dòng)態(tài)的獲得程序運(yùn)行時(shí)對(duì)象的結(jié)構(gòu)和信息。

reflect 包中提供了兩個(gè)基礎(chǔ)的關(guān)于反射的函數(shù)來(lái)獲取上述的接口和結(jié)構(gòu)體:

func TypeOf(i interface{}) Type

func ValueOf(i interface{}) Value

大體上可以這樣理解,TypeOf獲取對(duì)象的類(lèi)型信息,ValueOf獲取對(duì)象中存儲(chǔ)的值。

golang tag

golang中可以為結(jié)構(gòu)體的字段添加tag。golang本身的encoding/json包解析json使用了tag,一些開(kāi)源的orm框架如gorm,也使用了tag。tag可以方便的為結(jié)構(gòu)體的字段添加一些信息,用reflect可以讀取到,加以利用。

這是一個(gè)用tag標(biāo)記列名以實(shí)現(xiàn)結(jié)構(gòu)體自動(dòng)生成xlsx的例子:

```

type Employee struct{

ID int `xlsx:”工號(hào)”`

Name string `xlsx:”姓名”`

Email string `xlsx:”郵箱”`

}

func Outputxlsx(es []*Employee) ([]byte, error) {

xt := reflect.TypeOf(es[0])

xv := reflect.ValueOf(es[0])

rows := [][]interface{}{}

headers := []interface{}{}

for i := 0; i xt.Elem().NumField(); i++ {

head, ok := xt.Elem().Field(i).Tag.Lookup("xlsx")

if ok {

headers = append(headers, head)

}

}

for _, e := range es {

cells := []interface{}{}

xv := reflect.ValueOf(e)

for i := 0; i xv.Elem().NumField(); i++ {

_, ok := xt.Elem().Field(i).Tag.Lookup("xlsx")

if ok {

cells = append(cells, xv.Elem().Field(i).Interface())

}

}

rows = append(rows, cells)

}

file := xlsx.NewFile()

sheet, _ := file.AddSheet("sheet1")

row := sheet.AddRow()

for _, header := range headers {

row.AddCell().Value = fmt.Sprintf("%v", header)

}

for _, v := range rows {

row := sheet.AddRow()

for _, vv := range v {

row.AddCell().Value = fmt.Sprintf("%v", vv)

}

}

var buffer bytes.Buffer

if err := file.Write(buffer); err != nil {

return nil, err

}

return buffer.Bytes(), nil

}

```

golang反射框架Fx

Fx是一個(gè)golang版本的依賴(lài)注入框架,它使得golang通過(guò)可重用、可組合的模塊化來(lái)構(gòu)建golang應(yīng)用程序變得非常容易,可直接在項(xiàng)目中添加以下內(nèi)容即可體驗(yàn)Fx效果。

Fx是通過(guò)使用依賴(lài)注入的方式替換了全局通過(guò)手動(dòng)方式來(lái)連接不同函數(shù)調(diào)用的復(fù)雜度,也不同于其他的依賴(lài)注入方式,F(xiàn)x能夠像普通golang函數(shù)去使用,而不需要通過(guò)使用struct標(biāo)簽或內(nèi)嵌特定類(lèi)型。這樣使得Fx能夠在很多go的包中很好的使用。

接下來(lái)會(huì)提供一些Fx的簡(jiǎn)單demo,并說(shuō)明其中的一些定義。

1、一般步驟

大致的使用步驟就如下。下面會(huì)給出一些完整的demo

2、簡(jiǎn)單demo

將io.reader與具體實(shí)現(xiàn)類(lèi)關(guān)聯(lián)起來(lái)

輸出:

3、使用struct參數(shù)

前面的使用方式一旦需要進(jìn)行注入的類(lèi)型過(guò)多,可以通過(guò)struct參數(shù)方式來(lái)解決

輸出

如果通過(guò)Provide提供構(gòu)造函數(shù)是生成相同類(lèi)型會(huì)有什么問(wèn)題?換句話(huà)也就是相同類(lèi)型擁有多個(gè)值呢?

下面兩種方式就是來(lái)解決這樣的問(wèn)題。

4、使用struct參數(shù)+Name標(biāo)簽

在Fx未使用Name或Group標(biāo)簽時(shí)不允許存在多個(gè)相同類(lèi)型的構(gòu)造函數(shù),一旦存在會(huì)觸發(fā)panic。

輸出

上面通過(guò)Name標(biāo)簽即可完成在Fx容器注入相同類(lèi)型

5、使用struct參數(shù)+Group標(biāo)簽

使用group標(biāo)簽同樣也能完成上面的功能

輸出

基本上Fx簡(jiǎn)單應(yīng)用在上面的例子也做了簡(jiǎn)單講解

1、Annotated(位于annotated.go文件) 主要用于采用annotated的方式,提供Provide注入類(lèi)型

源碼中Name和Group兩個(gè)字段與前面提到的Name標(biāo)簽和Group標(biāo)簽是一樣的,只能選其一使用

2、App(位于app.go文件) 提供注入對(duì)象具體的容器、LiftCycle、容器的啟動(dòng)及停止、類(lèi)型變量及實(shí)現(xiàn)類(lèi)注入和兩者映射等操作

至于Provide和Populate的源碼相對(duì)比較簡(jiǎn)單易懂在這里不在描述

具體源碼

3、Extract(位于extract.go文件)

主要用于在application啟動(dòng)初始化過(guò)程通過(guò)依賴(lài)注入的方式將容器中的變量值來(lái)填充給定的struct,其中target必須是指向struct的指針,并且只能填充可導(dǎo)出的字段(golang只能通過(guò)反射修改可導(dǎo)出并且可尋址的字段),Extract將被Populate代替。 具體源碼

4、其他

諸如Populate是用來(lái)替換Extract的,而LiftCycle和inout.go涉及內(nèi)容比較多后續(xù)會(huì)單獨(dú)提供專(zhuān)屬文件說(shuō)明。

在Fx中提供的構(gòu)造函數(shù)都是惰性調(diào)用,可以通過(guò)invocations在application啟動(dòng)來(lái)完成一些必要的初始化工作:fx.Invoke(function); 通過(guò)也可以按需自定義實(shí)現(xiàn)LiftCycle的Hook對(duì)應(yīng)的OnStart和OnStop用來(lái)完成手動(dòng)啟動(dòng)容器和關(guān)閉,來(lái)滿(mǎn)足一些自己實(shí)際的業(yè)務(wù)需求。

Fx框架源碼解析

主要包括app.go、lifecycle.go、annotated.go、populate.go、inout.go、shutdown.go、extract.go(可以忽略,了解populate.go)以及輔助的internal中的fxlog、fxreflect、lifecycle

go語(yǔ)言的reflect(反射)

1、反射可以在運(yùn)行時(shí) 動(dòng)態(tài)獲取變量的各種信息 ,比如變量的類(lèi)型、類(lèi)別;

2、如果是結(jié)構(gòu)體變量,還可以獲取到結(jié)構(gòu)體本身的信息(包括結(jié)構(gòu)體的字段、方法);

3、通過(guò)反射,可以修改 變量的值 ,可以調(diào)用關(guān)聯(lián)的方法;

4、使用反射,需要import " reflect ".

5、示意圖:

1、不知道接口調(diào)用哪個(gè)函數(shù),根據(jù)傳入?yún)?shù)在運(yùn)行時(shí)確定調(diào)用的具體接口,這種需要對(duì)函數(shù)或方法反射。

例如以下這種橋接模式:

示例第一個(gè)參數(shù)funcPtr以接口的形式傳入函數(shù)指針,函數(shù)參數(shù)args以可變參數(shù)的形式傳入,bridge函數(shù)中可以用反射來(lái)動(dòng)態(tài)執(zhí)行funcPtr函數(shù)。

1、reflect.TypeOf(變量名),獲取變量的類(lèi)型,返回reflect.Type類(lèi)型。

2、reflect.ValueOf(變量名),獲取變量的值,返回reflect.Value類(lèi)型reflect.Value是一個(gè)結(jié)構(gòu)體類(lèi)型。

3、變量、interface{}和reflect.Value是可以互相轉(zhuǎn)換的,這點(diǎn)在實(shí)際開(kāi)發(fā)中,會(huì)經(jīng)常使用到。

1、reflect.Value.Kind,獲取變量的 類(lèi)別(Kind) ,返回的是一個(gè) 常量 。在go語(yǔ)言文檔中:

示例如下所示:

輸出如下:

Kind的范疇要比Type大。比如有Student和Consumer兩個(gè)結(jié)構(gòu)體,他們的 Type 分別是 Student 和 Consumer ,但是它們的 Kind 都是 struct 。

2、Type是類(lèi)型,Kind是類(lèi)別,Type和Kind可能是相同的,也可能是不同的。

3、通過(guò)反射可以在讓 變量 在 interface{} 和 Reflect.Value 之間相互轉(zhuǎn)換,這點(diǎn)在前面畫(huà)過(guò)示意圖。

4、使用反射的方式來(lái)獲取變量的值(并返回對(duì)應(yīng)的類(lèi)型),要求數(shù)據(jù)類(lèi)型匹配,比如x是int,那么久應(yīng)該使用reflect.Value(x).Int(),而不能使用其它的,否則報(bào)panic。

如果是x是float類(lèi)型的話(huà),也是要用reflect.Value(x).Float()。但是如果是struct類(lèi)型的話(huà),由于type并不確定,所以沒(méi)有相應(yīng)的方法,只能 斷言。

5、通過(guò)反射的來(lái)修改變量,注意當(dāng)使用SetXxx方法來(lái)設(shè)置需要通過(guò)對(duì)應(yīng)的指針類(lèi)型來(lái)完成,這樣才能改變傳入的變量的值,同時(shí)需要使用到reflect.Value.Elem()方法。

輸出num=20,即成功使用反射來(lái)修改傳進(jìn)來(lái)變量的值。

6、reflect.Value.Elem()應(yīng)該如何理解?


標(biāo)題名稱(chēng):go語(yǔ)言反射獲取參數(shù)名 go反射調(diào)用方法
鏈接URL:http://weahome.cn/article/hpisge.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部