反射是go語言學習中乙個比較難的點,需要好好探索一下。
我們知道,無論是int,float,bool等基礎資料型別,亦或是array,slice,map,chan等引用型別,當使用這些型別來定義的變數,在程式編譯時,編譯器已經知道變數的具體型別和具體值。
但很多時候,當我們使用介面型別(inte***ce{})定義變數時,介面型別的具體型別與具體值,需要在程式執行時才能確定,且可以動態變化,因此需要一種技術來檢測變數在程式執行中的具體型別和值。
go反射技術就是這樣一種用來檢查未知型別和值的機制與方法。
當我們需要實現乙個通用的函式時,比如實現乙個類似fmt.sprint這樣的列印函式時,可以根據不同的資料型別,返回出不同格式的資料,我們也實現乙個類似fmt.sprint()函式但只可以列印乙個引數的sprint函式,**如下:
type stringer inte***ce
func sprint(x inte***ce{}) string
return
"false"
default:
// 預設返回值
return
"???"
}}複製**
在上面列印函式中,我們只是判斷了幾種基礎型別,但這是不夠,還有許多態別沒有判斷,雖然我們可以在上面的switch結構中繼續增加分支判斷,但在實際的程式中,還更多自定義的未知型別,因此需要使用反射技術來實現。
go語言反射技術是由reflect包來實現,這個包主要定義了reflect.type和reflect.value兩個重要的型別。
reflect.type是乙個介面,代表乙個的具體型別,使用reflect.typeof()函式,可以返回reflect.type的實現,reflect.typeof()方法可以接收任何型別的引數,如下:
t := reflect.typeof(100)
fmt.println(t)//int
複製**
reflect.value是乙個reflect包中定義的結構體,代表乙個型別的具體值,使用reflect.valueof()函式可以返回乙個reflect.value值,reflect.valueof()可以接收任意型別的引數。
使用reflect.value中的type()方法,可以返回對應的reflect.type。
v := reflect.valueof(10)
fmt.println(v)
t := v.type()
fmt.println(t)
複製**
因此,我們可以使用反射來修改上面的spring函式。
func sprint(vv inte***ce{}) string
}複製**
golang提供的反射reflect包,是用於檢測型別、修改型別值、呼叫型別方法和其他操作的強大技術,在其他的庫或框架中都有使用,但還是應該慎用。
除了我們經常使用的fmt包是應用反射實現的之外,encoding/json、encoding/xml等包也是如此。
其實在一些web框架中,將http請求引數繫結到模型中,在orm框架中,將資料表查詢結果繫結到模型中,應用的都是反射技術。
Golang反射呼叫函式
首先,來看看這段 php view source print?1functionfoobar 4 funcs array 5 foobar foobar 6 hello foobar 7 8 funcs foobar 9 funcs hello 它會輸出 view source print?1mik...
Golang學習筆記 反射
反射讓我們可以在執行時獲取物件的型別資訊,比如檢視乙個結構體有多少字段,檢視函式的入參型別和返回值型別等。go提供了reflect.typeof 和reflect.valueof獲取任意物件的reflect.value和reflect.type,其中reflect.type是乙個介面型別,該介面提供...
golang的反射機制
首先,golang反射,分為 t reflect.typeof n num t.numfield t reflect.typeof n num t.field n int 從0開始,以宣告的順序排序type students struct func stu students t func stu s...