反射能在執行期探知物件的型別資訊和記憶體結構。
也是實現元程式設計的重要手段。
反射所需的全部資訊都源自介面變數。介面變數處儲存自身型別外,還會儲存實際物件的型別資料。
//將任何傳入的物件轉換為介面型別
func
typeof
(i inte***ce()
) type
func
valueof
(i inte***ce()
) value
type與kind
type:真實型別(靜態型別)
kind:基礎結構(底層型別)
//type/kind
var a,b x =1,
2var c y =
3ta,tb,tc := reflect.
typeof
(a), reflect.
typeof
(b),reflect.
typeof
(c)fmt.
println
( ta == tb, tb == tc)
//a,b的type不同,但是kind相同
fmt.
println
(ta.
kind()
== tb.
kind()
,ta.
kind()
== tc.
kind()
)fmt.
println
(ta,tb,tc)
main.x main.y
構造基礎復合型別
//構造復合型別
arr := reflect.
arrayof(10
,reflect.
typeof
(byte(0
)))m := reflect.
mapof
(reflect.
typeof(""
),reflect.
typeof(0
))fmt.
println
(arr,m)
//[10]uint8 map[string]int
基型別和指標型別不同
//區分基型別與指標型別
tcp := reflect.
typeof
(&c)
fmt.
println
(tc,tcp,tc == tcp.
elem()
) *main.y true
elem()返回指標、陣列、切片、字典(value)或通道的基型別
同時,反射能探知當前包或外包的非匯出結構成員
可用反射提取struct tag,還可以自動分解。常用於orm對映或資料格式驗證。
物件例項資料讀寫
//反射-值
a :=
100va,vp := reflect.
valueof
(a),reflect.
valueof
(&a)
.elem()
fmt.
println
(va.
canaddr()
, va.
canset()
)//false:位址不可取,值不可改變
fmt.
println
(vp.
canaddr()
,vp.
canset()
)//true
不能對非匯出字段直接進行設定操作,無論當前包還是外包
可通過inte***ce方法進行型別推斷和轉換
介面有兩種nil狀態(nil/(*int)nil),可用isnil判斷值是否nil
var n1 inte***ce
=nil
var n2 inte***ce=(
*int)(
nil)
fmt.
println
(n1 ==
nil,n2 ==
nil)
//true false
fmt.
println
(reflect.
valueof
(n2)
.isnil()
)//true
//panic: reflect: call of reflect.value.isnil on zero value
go語言基礎 反射 reflect
反射reflect struct reflect.typeof i inte ce type 獲取結構體的字段的型別,欄位名 方法的型別,方法的名字 packagemain import fmt reflect typepersonstruct func p person say msg strin...
Go中反射(reflect)的應用
package main import fmt reflect type monster struct 顯示s的值 func s monster print 返回兩個數的和 func s monster getsum n1,n2 int int 設定s結構體的在 func s monster set...
GO語言學習
sudo apt get install golang但是用ubuntu的庫安裝有幾個不好的地方 因此建議不要使用ubuntu的庫安裝golang環境 golang社群的安裝指導 wget tar c usr local zxf go1.6.2.linux amd64.tar.gz設定環境變數,修改...