go語言反射獲取屬性值,go語言 反射

關于反射

在計算機科學領域,反射是指一類應用,它們能夠自描述和自控制。也就是說,這類應用通過采用某種機制來實現對自己行為的描述(self-representation)和監測(examination),并能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。

為吉林等地區用戶提供了全套網頁設計制作服務,及吉林網站建設行業解決方案。主營業務為成都做網站、網站設計、吉林網站設計,以傳統方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業、用心的態度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

每種語言的反射模型都不同,并且有些語言根本不支持反射。Golang語言實現了反射,反射機制就是在運行時動態的調用對象的方法和屬性,官方自帶的reflect包就是反射相關的,只要包含這個包就可以使用。

多插一句,Golang的gRPC也是通過反射實現的。

在講反射之前,先來看看Golang關于類型設計的一些原則

接下來要講的反射,就是建立在類型之上的,Golang的指定類型的變量的類型是靜態的(也就是指定int、string這些的變量,它的type是static type),在創建變量的時候就已經確定,反射主要與Golang的interface類型相關(它的type是concrete type),只有interface類型才有反射一說。

在Golang的實現中,每個interface變量都有一個對應pair,pair中記錄了實際變量的值和類型:

value是實際變量值,type是實際變量的類型。一個interface{}類型的變量包含了2個指針,一個指針指向值的類型【對應concrete type】,另外一個指針指向實際的值【對應value】。

例如,創建類型為*os.File的變量,然后將其賦給一個接口變量r:

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

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

interface及其pair的存在,是Golang中實現反射的前提,理解了pair,就更容易理解反射。反射就是用來檢測存儲在接口變量內部(值value;類型concrete type) pair對的一種機制。

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

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

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

已知類型后轉換為其對應的類型的做法如下,直接通過Interface方法然后強制轉換,如下:

示例如下:

很多情況下,我們可能并不知道其具體類型,那么這個時候,該如何做呢?需要我們進行遍歷探測其Filed來得知,示例如下:

通過運行結果可以得知獲取未知類型的interface的具體變量及其類型的步驟為:

通過運行結果可以得知獲取未知類型的interface的所屬方法(函數)的步驟為:

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

示例如下:

這算是一個高級用法了,前面我們只說到對類型、變量的幾種反射的用法,包括如何獲取其值、其類型、如果重新設置新值。但是在工程應用中,另外一個常用并且屬于高級的用法,就是通過reflect來進行方法【函數】的調用。比如我們要做框架工程的時候,需要可以隨意擴展方法,或者說用戶可以自定義方法,那么我們通過什么手段來擴展讓用戶能夠自定義呢?關鍵點在于用戶的自定義方法是未可知的,因此我們可以通過reflect來搞定

示例如下:

Golang的反射很慢,這個和它的API設計有關。在 java 里面,我們一般使用反射都是這樣來弄的。

這個取得的反射對象類型是 java.lang.reflect.Field。它是可以復用的。只要傳入不同的obj,就可以取得這個obj上對應的 field。

但是Golang的反射不是這樣設計的:

這里取出來的 field 對象是 reflect.StructField 類型,但是它沒有辦法用來取得對應對象上的值。如果要取值,得用另外一套對object,而不是type的反射

這里取出來的 fieldValue 類型是 reflect.Value,它是一個具體的值,而不是一個可復用的反射對象了,每次反射都需要malloc這個reflect.Value結構體,并且還涉及到GC。

Golang reflect慢主要有兩個原因

上述詳細說明了Golang的反射reflect的各種功能和用法,都附帶有相應的示例,相信能夠在工程應用中進行相應實踐,總結一下就是:

如何通過反射來獲取類的靜態屬性值

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

go語言的reflect(反射)

1、反射可以在運行時 動態獲取變量的各種信息 ,比如變量的類型、類別;

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

3、通過反射,可以修改 變量的值 ,可以調用關聯的方法;

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

5、示意圖:

1、不知道接口調用哪個函數,根據傳入參數在運行時確定調用的具體接口,這種需要對函數或方法反射。

例如以下這種橋接模式:

示例第一個參數funcPtr以接口的形式傳入函數指針,函數參數args以可變參數的形式傳入,bridge函數中可以用反射來動態執行funcPtr函數。

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

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

3、變量、interface{}和reflect.Value是可以互相轉換的,這點在實際開發中,會經常使用到。

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

示例如下所示:

輸出如下:

Kind的范疇要比Type大。比如有Student和Consumer兩個結構體,他們的 Type 分別是 Student 和 Consumer ,但是它們的 Kind 都是 struct 。

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

3、通過反射可以在讓 變量 在 interface{} 和 Reflect.Value 之間相互轉換,這點在前面畫過示意圖。

4、使用反射的方式來獲取變量的值(并返回對應的類型),要求數據類型匹配,比如x是int,那么久應該使用reflect.Value(x).Int(),而不能使用其它的,否則報panic。

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

5、通過反射的來修改變量,注意當使用SetXxx方法來設置需要通過對應的指針類型來完成,這樣才能改變傳入的變量的值,同時需要使用到reflect.Value.Elem()方法。

輸出num=20,即成功使用反射來修改傳進來變量的值。

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

go語言中的反射

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{}

//通過反射設置變量的值

func reflectSetValue1(x interface{}){

v := reflect.ValueOf(x)

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

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

}

}

//通過反射設置變量的值

func reflectSetValue2(x interface{}){

v := reflect.ValueOf(x)

//反射中使用Elem()獲取指針對應的值

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)

}

反射怎么獲取類屬性類型

反射可以獲取到屬性類型,Field類里面有個方法,getType()就是獲取屬性類型的。。。

下面是個示例代碼。。。

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();

這個來獲取類型。。。。

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

分享文章:go語言反射獲取屬性值,go語言 反射
分享URL:http://m.kartarina.com/article18/hddidp.html

成都網站建設公司_創新互聯,為您提供云服務器企業建站定制網站虛擬主機網站收錄企業網站制作

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

手機網站建設
主站蜘蛛池模板: 亚洲A∨无码一区二区三区| 无码精品人妻一区二区三区影院 | 日本精品人妻无码免费大全| 无码少妇一区二区浪潮免费| 无码色偷偷亚洲国内自拍| 无码孕妇孕交在线观看| 无码人妻av一区二区三区蜜臀| 人妻丰满熟妇AV无码区HD| 国产成人无码AV麻豆| 国产在线精品无码二区| 2020无码专区人妻系列日韩| 熟妇人妻中文字幕无码老熟妇| 国产av无码专区亚洲av毛片搜| 亚洲熟妇无码爱v在线观看| 一本色道久久HEZYO无码| 国产精品成人无码久久久久久 | 国产精品亚洲专区无码不卡 | 亚洲av无码一区二区三区观看| 精品无码久久久久久久久水蜜桃 | 久久亚洲精品无码观看不卡| 曰韩人妻无码一区二区三区综合部| 国产aⅴ激情无码久久| 国模无码视频一区| 亚洲AV永久无码天堂影院 | 亚洲av无码专区首页| 人妻少妇偷人精品无码| 亚洲精品无码久久千人斩| 亚洲?v无码国产在丝袜线观看| 无码国产精成人午夜视频不卡 | 亚洲va中文字幕无码久久不卡| 国产成人无码精品一区不卡 | 国产精品无码一区二区三区不卡 | 永久免费av无码不卡在线观看 | 亚洲av日韩av永久无码电影 | 国模无码人体一区二区| 亚洲高清无码在线观看| 无码人妻少妇伦在线电影| 无码人妻精品一区二区三区99不卡| 精品一区二区三区无码视频| 日韩毛片无码永久免费看| 亚欧无码精品无码有性视频|