reflect使能夠在執行期得知物件的型別資訊和記憶體結構,全部資訊**自介面變數。
首先區分 type 和 kind 。
type:真實型別,靜態型別。
kind:基礎結構類別,底層型別。
type x int
func
main()
) type 型別
v := reflect.
valueof
(a)// func valueof(i inte***ce{}) value 值
fmt.
println
(v,t.
name()
,t.kind()
)// 100 x int
}
傳入物件區分基礎結構和指標型別,typeof(x) != typeof(&x)
方法elem()返回指標指向的物件型別,(陣列,slice,map或channel)中的元素型別
遍歷結構體的字段,必須獲取結構體的基礎型別。如果傳人的是結構體指標,需要用elem()返回型別。匿名字段需要再巢狀一層,type.field(i).anonymous可判斷是否為匿名字段,type.field(i).field(x)獲取匿名巢狀字段,可用多級索引直接訪問匿名字段
type user struct
type manager struct
func
main()
)//0表示最外層第0個字段 1表示巢狀第一層第乙個字段
fmt.
println
(age.name,age.type)
// age int /則表示user.name /表示manager.name
//可按名稱直接查詢字段 有同名遮蔽
name,
_ := t.
fieldbyname
("name"
) fmt.
println
(name.name,name.type)
// name int
}
方法method()可輸出方法集,區分指標和基型別
反射 能探知當前包或外包的非匯出結構成員
反射可以提取stuct tag
type user struct
func
main()
}
func (t *rtype) implements(u reflect.type) bool // 判斷 t 型別是否實現了 u 介面。
func (t *rtype) convertibleto(u reflect.type) bool // 判斷 t 型別的值可否轉換為 u 型別。
func (t *rtype) assignableto(u reflect.type) bool // 判斷 t 型別的值可否賦值給 u 型別。
要想修改目標物件,需要傳入指標,傳入指標就需要使用elem()獲取目標物件。
a:=
100va ,vp := reflect.
valueof
(a),reflect.
valueof
(&a)
.elem()
fmt.
println
(va.
canaddr()
,va.
canset()
,vp.
canaddr()
,vp.
canset()
)// false false true true
非匯出字段不能直接進行設定操作,無論是當前包還是外包,可定址時,可使用unsafa包進行設定。
可通過inte***ce()方法返回介面型別進行型別推斷和轉換,轉換為原始型別可進行引數修改
介面有兩種nil
var a inte***ce
// a == nil
var b inte***ce=(
*int)(
int)
// b!=nil ***reflect.valueof(b).isnil=true 判斷值為nil
動態呼叫方法
無法呼叫非匯出方法。
js ES6學習筆記 Reflect
1 reflect物件與proxy物件一樣,也是 es6 為了操作物件而提供的新 api。reflect物件的設計目的有這樣幾個。2 reflect.get方法查詢並返回target物件的name屬性,如果沒有該屬性,則返回undefined。3 reflect.set方法設定target物件的na...
GO語言學習 反射reflect
反射能在執行期探知物件的型別資訊和記憶體結構。也是實現元程式設計的重要手段。反射所需的全部資訊都源自介面變數。介面變數處儲存自身型別外,還會儲存實際物件的型別資料。將任何傳入的物件轉換為介面型別 func typeof i inte ce type func valueof i inte ce va...
閉包學習筆記
作用域的定義 變數起作用的範圍 區域性變數的作用域是它自己所在的函式及其巢狀函式 示例1 function getcounter var counter getcounter counter counter counter 釋放閉包與它的環境 counter null counter getcoun...