12 Go語言 反射詳解

2021-09-25 02:14:53 字數 3831 閱讀 4849

1. 反射定義:

可以在執行時動態獲取變數的相關資訊。 import (「reflect」)

官方對此有個非常簡明的介紹,兩句話耐人尋味:

反射提供一種讓程式檢查自身結構的能力。再精確點的描述是「反射是一種檢查inte***ce變數的底層型別和值的機制」;

反射是困惑的源泉;(想深入了解反射,必須深入理解型別和介面概念。)

2. 方法:

reflect.typeof,獲取變數的型別,返回reflect.type型別 ;

reflect.valueof,獲取變數的值,返回reflect.value型別;

reflect.value.kind,獲取變數的類別,返回乙個常量;

reflect.value.inte***ce(),轉換成inte***ce{}型別;

reflect.valueof(x).float(),獲取變數的值;(reflect.valueof(x).int()reflect.valueof(x).string()reflect.valueof(x).bool()

reflect.value.setxx相關方法,通過反射的來改變變數的值

,比如:reflect.value.setfloat(),設定浮點數;reflect.value.setint(),設定整數;reflect.value.setstring(),設定字串

舉個例子:

package main

import

("fmt"

"reflect"

)func

main()

執行結果如下圖:

再比如:

package main

import

("fmt"

"reflect"

)func

main()

3. 用反射操作結構體

reflect.value.numfield()獲取結構體中字段的個數

reflect.value.method(n).call來呼叫結構體中的方法

舉個例子(通過反射操作結構體):

package main

import

("fmt"

"reflect"

)type notknowntype struct

func

(n notknowntype)

string()

string

var secret inte***ce

= notknowntype

func

main()

results := value.

method(0

).call

(nil

) fmt.

println

(results)

// [ada - go - oberon]

}

執行結果如下圖:

通過反射修改結構體:

package main

import

("fmt"

"reflect"

)type t struct

func

main()

s := reflect.

valueof

(&t)

.elem()

typeoft := s.

type()

for i :=

0; i < s.

numfield()

; i++

s.field(0

).setint(77

) s.

field(1

).setstring

("sunset strip"

) fmt.

println

("t is now"

, t)

}

4. 反射三定律:

inte***ce型別有個(value,type)對,而反射就是檢查inte***ce的這個(value, type)對的。具體一點說就是go提供一組方法提取inte***ce的value,提供另一組方法提取inte***ce的type.

反射包裡有兩個介面型別要先了解一下.

reflect.type 提供一組介面處理inte***ce的型別,即(value, type)中的type

reflect.value提供一組介面處理inte***ce的值,即(value, type)中的value

反射第一定律:反射可以將inte***ce型別變數轉換成反射物件

package main

import

("fmt"

"reflect"

)func

main()

執行結果如下:

注意:反射是針對inte***ce型別變數的,其中typeof()和valueof()接受的引數都是inte***ce{}型別的,也即x值是被轉成了inte***ce傳入的。

反射第二定律:反射可以將反射物件還原成inte***ce物件

package main

import

("fmt"

"reflect"

)//之所以叫'反射',反射物件與inte***ce物件是可以互相轉化的

func

main()

執行結果如下:

物件x轉換成反射物件v,v又通過inte***ce()介面轉換成inte***ce物件,inte***ce物件通過.(float64)型別斷言獲取float64型別的值。

反射第三定律:反射物件可修改,value值必須是可設定的

通過反射可以將inte***ce型別變數轉換成反射物件,可以使用該反射物件設定其持有的值。

reflect.value提供了elem()方法,可以獲得指標向指向的value。看如下**:

package main

import

("reflect"

"fmt"

)func

main()

執行結果如下圖:

對反射的深入理解,個人覺得還需要繼續看的內容:

參考業界,尤其是開源框架中是如何使用反射的

研究反射實現原理,**其效能優化的手段

1 2Go語言安裝

go語言編譯器及輔助工具可用於 windows macos 和linux 等作業系統。推薦盡可能使用作業系統自帶的包管理器來安裝go語言的 二進位制發行包 如 windows go1.11.4.windows amd64.msi maxos go1.11.4.darwin amd64.pkg lin...

12 Go語言基礎 通道 channel

說道通道 channel,不得不提go語言的併發程式設計模型 csp。go語言提倡,通過通訊來共享記憶體。goroutines 可以看做是go的乙個併發執行緒。基於系統執行緒。每啟動乙個goroutine的堆初始化占用是2 4k,可以擴大到1g。這也是go語言可以啟動成千上萬個goroutine的原...

1 2Go語言開發環境搭建

sdk 1 什麼是sdk?sdk的全稱是 software development kit 軟體開發工具包 sdk是提供給開發人員使用,包含了對應開發語言的工具包 環境變數 1 為什麼需要配置環境變數?在dos命令中鍵入go命令,會出現錯誤提示,原因是開啟dos的當前資料夾目錄 沒有go這個可執行的...