欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

go語(yǔ)言反射獲取屬性值,go語(yǔ)言 反射

關(guān)于反射

在計(jì)算機(jī)科學(xué)領(lǐng)域,反射是指一類應(yīng)用,它們能夠自描述和自控制。也就是說(shuō),這類應(yīng)用通過(guò)采用某種機(jī)制來(lái)實(shí)現(xiàn)對(duì)自己行為的描述(self-representation)和監(jiān)測(cè)(examination),并能根據(jù)自身行為的狀態(tài)和結(jié)果,調(diào)整或修改應(yīng)用所描述行為的狀態(tài)和相關(guān)的語(yǔ)義。

為吉林等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及吉林網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、吉林網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

每種語(yǔ)言的反射模型都不同,并且有些語(yǔ)言根本不支持反射。Golang語(yǔ)言實(shí)現(xiàn)了反射,反射機(jī)制就是在運(yùn)行時(shí)動(dòng)態(tài)的調(diào)用對(duì)象的方法和屬性,官方自帶的reflect包就是反射相關(guān)的,只要包含這個(gè)包就可以使用。

多插一句,Golang的gRPC也是通過(guò)反射實(shí)現(xiàn)的。

在講反射之前,先來(lái)看看Golang關(guān)于類型設(shè)計(jì)的一些原則

接下來(lái)要講的反射,就是建立在類型之上的,Golang的指定類型的變量的類型是靜態(tài)的(也就是指定int、string這些的變量,它的type是static type),在創(chuàng)建變量的時(shí)候就已經(jīng)確定,反射主要與Golang的interface類型相關(guān)(它的type是concrete type),只有interface類型才有反射一說(shuō)。

在Golang的實(shí)現(xiàn)中,每個(gè)interface變量都有一個(gè)對(duì)應(yīng)pair,pair中記錄了實(shí)際變量的值和類型:

value是實(shí)際變量值,type是實(shí)際變量的類型。一個(gè)interface{}類型的變量包含了2個(gè)指針,一個(gè)指針指向值的類型【對(duì)應(yīng)concrete type】,另外一個(gè)指針指向?qū)嶋H的值【對(duì)應(yīng)value】。

例如,創(chuàng)建類型為*os.File的變量,然后將其賦給一個(gè)接口變量r:

接口變量r的pair中將記錄如下信息:(tty, *os.File),這個(gè)pair在接口變量的連續(xù)賦值過(guò)程中是不變的,將接口變量r賦給另一個(gè)接口變量w:

接口變量w的pair與r的pair相同,都是:(tty, *os.File),即使w是空接口類型,pair也是不變的。

interface及其pair的存在,是Golang中實(shí)現(xiàn)反射的前提,理解了pair,就更容易理解反射。反射就是用來(lái)檢測(cè)存儲(chǔ)在接口變量?jī)?nèi)部(值value;類型concrete type) pair對(duì)的一種機(jī)制。

既然反射就是用來(lái)檢測(cè)存儲(chǔ)在接口變量?jī)?nèi)部(值value;類型concrete type) pair對(duì)的一種機(jī)制。那么在Golang的reflect反射包中有什么樣的方式可以讓我們直接獲取到變量?jī)?nèi)部的信息呢? 它提供了兩種類型(或者說(shuō)兩個(gè)方法)讓我們可以很容易的訪問(wèn)接口變量?jī)?nèi)容,分別是reflect.ValueOf() 和 reflect.TypeOf(),看看官方的解釋

reflect.TypeOf()是獲取pair中的type,reflect.ValueOf()獲取pair中的value,示例如下:

當(dāng)執(zhí)行reflect.ValueOf(interface)之后,就得到了一個(gè)類型為”relfect.Value”變量,可以通過(guò)它本身的Interface()方法獲得接口變量的真實(shí)內(nèi)容,然后可以通過(guò)類型判斷進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換為原有真實(shí)類型。不過(guò),我們可能是已知原有類型,也有可能是未知原有類型,因此,下面分兩種情況進(jìn)行說(shuō)明。

已知類型后轉(zhuǎn)換為其對(duì)應(yīng)的類型的做法如下,直接通過(guò)Interface方法然后強(qiáng)制轉(zhuǎn)換,如下:

示例如下:

很多情況下,我們可能并不知道其具體類型,那么這個(gè)時(shí)候,該如何做呢?需要我們進(jìn)行遍歷探測(cè)其Filed來(lái)得知,示例如下:

通過(guò)運(yùn)行結(jié)果可以得知獲取未知類型的interface的具體變量及其類型的步驟為:

通過(guò)運(yùn)行結(jié)果可以得知獲取未知類型的interface的所屬方法(函數(shù))的步驟為:

reflect.Value是通過(guò)reflect.ValueOf(X)獲得的,只有當(dāng)X是指針的時(shí)候,才可以通過(guò)reflec.Value修改實(shí)際變量X的值,即:要修改反射類型的對(duì)象就一定要保證其值是“addressable”的。

示例如下:

這算是一個(gè)高級(jí)用法了,前面我們只說(shuō)到對(duì)類型、變量的幾種反射的用法,包括如何獲取其值、其類型、如果重新設(shè)置新值。但是在工程應(yīng)用中,另外一個(gè)常用并且屬于高級(jí)的用法,就是通過(guò)reflect來(lái)進(jìn)行方法【函數(shù)】的調(diào)用。比如我們要做框架工程的時(shí)候,需要可以隨意擴(kuò)展方法,或者說(shuō)用戶可以自定義方法,那么我們通過(guò)什么手段來(lái)擴(kuò)展讓用戶能夠自定義呢?關(guān)鍵點(diǎn)在于用戶的自定義方法是未可知的,因此我們可以通過(guò)reflect來(lái)搞定

示例如下:

Golang的反射很慢,這個(gè)和它的API設(shè)計(jì)有關(guān)。在 java 里面,我們一般使用反射都是這樣來(lái)弄的。

這個(gè)取得的反射對(duì)象類型是 java.lang.reflect.Field。它是可以復(fù)用的。只要傳入不同的obj,就可以取得這個(gè)obj上對(duì)應(yīng)的 field。

但是Golang的反射不是這樣設(shè)計(jì)的:

這里取出來(lái)的 field 對(duì)象是 reflect.StructField 類型,但是它沒(méi)有辦法用來(lái)取得對(duì)應(yīng)對(duì)象上的值。如果要取值,得用另外一套對(duì)object,而不是type的反射

這里取出來(lái)的 fieldValue 類型是 reflect.Value,它是一個(gè)具體的值,而不是一個(gè)可復(fù)用的反射對(duì)象了,每次反射都需要malloc這個(gè)reflect.Value結(jié)構(gòu)體,并且還涉及到GC。

Golang reflect慢主要有兩個(gè)原因

上述詳細(xì)說(shuō)明了Golang的反射reflect的各種功能和用法,都附帶有相應(yīng)的示例,相信能夠在工程應(yīng)用中進(jìn)行相應(yīng)實(shí)踐,總結(jié)一下就是:

如何通過(guò)反射來(lái)獲取類的靜態(tài)屬性值

Field.get(null) 附上文檔 public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException返回指定對(duì)象上此 Field 表示的字段的值。如果該值是一個(gè)基本類型值,則自動(dòng)將其包裝在一個(gè)對(duì)象中。

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

1、反射可以在運(yùn)行時(shí) 動(dòng)態(tà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(變量名),獲取變量的類型,返回reflect.Type類型。

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

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

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

示例如下所示:

輸出如下:

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

2、Type是類型,Kind是類別,Type和Kind可能是相同的,也可能是不同的。

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

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

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

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

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

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

go語(yǔ)言中的反射

import (

"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)

}

反射怎么獲取類屬性類型

反射可以獲取到屬性類型,F(xiàn)ield類里面有個(gè)方法,getType()就是獲取屬性類型的。。。

下面是個(gè)示例代碼。。。

public

static

void

main(String

args[])

{

People

peo

=

new

People();

Class

cla

=

People.class;

try

{

Field[]

fields

=

cla.getFields();

for(Field

field:fields){

Class

c

=

field.getType();

if(c==String.class){

field.set(peo,

"EMPTY");

}else

if(c==Integer.class){

field.set(peo,

0);

}

}

}

catch

(SecurityException

e)

{

//

TODO

Auto-generated

catch

block

e.printStackTrace();

}catch

(IllegalArgumentException

e)

{

//

TODO

Auto-generated

catch

block

e.printStackTrace();

}

catch

(IllegalAccessException

e)

{

//

TODO

Auto-generated

catch

block

e.printStackTrace();

}

}

主要就是用Class

c

=

field.getType();

這個(gè)來(lái)獲取類型。。。。

希望能幫到你。。。仍有問(wèn)題可以Hi我。。。或者直接追問(wèn)。。。

分享文章:go語(yǔ)言反射獲取屬性值,go語(yǔ)言 反射
分享URL:http://chinadenli.net/article18/hddidp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器企業(yè)建站定制網(wǎng)站、虛擬主機(jī)、網(wǎng)站收錄、企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)