您好,登錄后才能下訂單哦!
這篇文章主要介紹“Golang reflect反射如何使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Golang reflect反射如何使用”文章能幫助大家解決問題。
首先有一段以下結構體的定義
type User struct { UserName string UserId int `name:"uid"` }
初始化一個結構體的實例
u := User{"octoboy", 101}
首先獲取變量的Type變量
t := reflect.TypeOf(u)
需要注意的是,如果傳入的u是個指針,比如&User{"octoboy", 101}
if t.Kind() == reflect.Ptr { t = t.Elem() }
這里通過Kind()函數獲取變量的類型,判斷如果類型為指針 需要使用Elem()獲取指針指向的內容。
然后遍歷結構體的字段,獲取其字段名稱
for i := 0; i < t.NumField(); i++ { fmt.Println(t.Field(i).Name) }
輸出結果:
UserName
UserId
v := reflect.ValueOf(u) if v.Kind() == reflect.Ptr { //類型為指針 需要取elem v = v.Elem() }
獲取字段的值或者賦值,需要用到ValueOf方法
for i := 0; i < v.NumField(); i++ { //v.Field(i).Int() v.Field(i).String() 都可以把值返回出來,相當于斷言 類型不匹配會直接panic //直接斷成interface 任意類型 fmt.Println(v.Field(i).Interface()) }
輸出結果:
zyg
101
繼續輸出成員變量的類型
for i := 0; i < v.NumField(); i++ { fmt.Println(v.Field(i).Kind()) }
輸出結果:
string
int
//設置字段值 va := reflect.ValueOf(&u) //這里必須使用指針 否則后面調用Set無法使用無地址的值 if va.Kind() == reflect.Ptr { //類型為指針 需要取elem 意為取它指向的內容值 va = va.Elem() for i := 0; i < va.NumField(); i++ { //兩種方法取設置字段的值,第二種更為統一 if va.Field(i).Kind() == reflect.String { //重要 如果需要使用set取修改u中的值,需要在ValueOf中傳入u的地址。否則會因為SetString使用了一個不能被尋址的值而造成panic va.Field(i).SetString("octoboy") } if va.Field(i).Kind() == reflect.Int { va.Field(i).Set(reflect.ValueOf(123)) } }
//練手 values := []interface{}{"octoboy", 123} for i := 0; i < va.NumField(); i++ { if reflect.ValueOf(values[i]).Kind() == va.Field(i).Kind() { va.Field(i).Set(reflect.ValueOf(values[i])) } }
打印以上兩種結構題變量
輸出結果:
&{octoboy 123}
有如下代碼
//練習 把map映射成struct set := map[string]interface{}{ "UserName": "zyg", "UserId": 101, "Age": 19, "Sex": 1, } user := &User{} MapToStruct(set, user) fmt.Println(user)
要求將map映射到user結構題中,即如果User的字段名如存在于map的key中,則將對應的value值賦給user結構題的成員變量
有如下實現
//str類型為interface{} 代表可以傳入任意的結構體 func MapToStruct(m map[string]interface{}, str interface{}) { val := reflect.ValueOf(str) if val.Kind() != reflect.Ptr {//必須是指針 否則無法用Set賦值 panic(any("must be ptr!")) } val = val.Elem() if val.Kind() != reflect.Struct { //指針指向的必須是結構體 panic(any("must be struct")) } for i := 0; i < val.NumField(); i++ { name := val.Type().Field(i).Name //value轉type后取字段名稱 if v, ok := m[name]; ok { //如果根據tag做映射,就使用val.Type().Field(i).Tag.Get("name")作為key if reflect.ValueOf(v).Kind() == val.Field(i).Kind() { val.Field(i).Set(reflect.ValueOf(v)) } } } }
關于“Golang reflect反射如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。