您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)Go語言中怎么實現(xiàn)結(jié)構(gòu)體反射,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
結(jié)構(gòu)體
type Student struct { Name string `json:"name" describe:"姓名"` Age int `json:"age" describe:"年齡"` Gender bool `json:"gender" describe:"性別"` Hobby []string `json:"hobby" describe:"愛好"` }
main
func main() { //實例化結(jié)構(gòu)體 var s1 = Student{ Name: "張三", Age: 18, Gender: true, Hobby: []string{"吃", "喝", "pia", "玩"}, } var t = reflect.TypeOf(s1) fmt.Println(t.Name()) //Student fmt.Println(t.Kind()) //struct fmt.Println(t.NumField()) //結(jié)果:4,表示多少個字段 for i := 0; i < t.NumField(); i++ { field := t.Field(i)//每個結(jié)構(gòu)體對象 /* {Name string json:"name" describe:"姓名" 0 [0] false} {Age int json:"age" describe:"年齡" 16 [1] false} {Gender bool json:"gender" describe:"性別" 24 [2] false} {Hobby []string json:"hobby" describe:"愛好" 32 [3] false} */ //fmt.Println(field) fmt.Println("------") fmt.Printf("field.Name:%v\n",field.Name) fmt.Printf("field.Index:%v\n",field.Index) fmt.Printf("field.Type:%v\n",field.Type) fmt.Printf("field.Tag:%v\n",field.Tag.Get("describe")) } }
執(zhí)行結(jié)果
單獨(dú)反射指定字段信息
main代碼
func main() { //實例化結(jié)構(gòu)體 var s1 = Student{ Name: "張三", Age: 18, Gender: true, Hobby: []string{"吃", "喝", "pia", "玩"}, } var t = reflect.TypeOf(s1) genderField, ok := t.FieldByName("Gender") if ok { fmt.Println(genderField.Name) //Gender fmt.Println(genderField.Index) //[2] fmt.Println(genderField.Type) //bool fmt.Println(genderField.Tag.Get("describe")) //性別 } }
ValueOf
上述的代碼只能用的是TypeOf,只能返回類型等信息,相對來說不是太智能,ValueOf可以獲取值,同樣也能獲取類型,相對來說比TypeOf好一點(diǎn)。
示例代碼
main
func main() { //實例化結(jié)構(gòu)體 var s1 = Student{ Name: "張三", Age: 18, Gender: true, Hobby: []string{"吃", "喝", "pia", "玩"}, } var v = reflect.ValueOf(s1) for i := 0; i < v.NumField(); i++ { field :=v.Field(i) fmt.Println("------") fmt.Printf("Kind:%v\n",field.Kind()) fmt.Printf("值:%v\n",field.Interface()) } }
執(zhí)行結(jié)果
反射方法
上述我們反射的都是值,有沒有反射是否可以反射函數(shù),并且調(diào)用函數(shù)呢??
結(jié)構(gòu)體和綁定函數(shù)代碼
type Student struct { Name string `json:"name" describe:"姓名"` Age int `json:"age" describe:"年齡"` Gender bool `json:"gender" describe:"性別"` Hobby []string `json:"hobby" describe:"愛好"` } //無參方法 func (this Student) Say() { fmt.Printf("我是%v,我的年齡是%v,我的性別是%v,我的愛好是%v\n", this.Name, this.Age, this.Gender, this.Hobby) } //有參數(shù)方法 func (this Student) Jump(distance int) { fmt.Printf("我是%v,我跳遠(yuǎn)跳了%v米\n", this.Name, distance) }
main
func main() { //實例化結(jié)構(gòu)體 var s1 = Student{ Name: "張三", Age: 18, Gender: true, Hobby: []string{"吃", "喝", "pia", "玩"}, } var t = reflect.TypeOf(s1) var v = reflect.ValueOf(s1) fmt.Println(v.NumMethod(),v.NumField()) for i := 0; i < v.NumMethod(); i++ { method := v.Method(i) fmt.Println("--------") fmt.Println(method)//0x48c4e0 函數(shù)地址 fmt.Println(method.Type())//func(int) 函數(shù)類型,形參和返回值 fmt.Println(t.Method(i).Name)//Jump,函數(shù)名,注意,由t來調(diào)用的 } }
執(zhí)行結(jié)果
反射調(diào)用函數(shù)
func main() { //實例化結(jié)構(gòu)體 var s1 = Student{ Name: "張三", Age: 18, Gender: true, Hobby: []string{"吃", "喝", "pia", "玩"}, } var v = reflect.ValueOf(s1) //通過反射調(diào)用函數(shù) //調(diào)用Jump函數(shù) //反射調(diào)用函數(shù)必須傳一個參數(shù),不管有沒有形參都要傳 //var args = []reflect.Value{} //v.MethodByName("Say").Call(args) //如果需要傳參數(shù) //參數(shù)需要用reflect.ValueOf(1) 強(qiáng)轉(zhuǎn)一下 var args = []reflect.Value{reflect.ValueOf(2)} v.MethodByName("Jump").Call(args) }
注:注意第14行和20行代碼區(qū)別,如果要傳參數(shù),參考第20行代碼。
執(zhí)行結(jié)果
反射注意事項
在平常開發(fā)中,盡量慎用反射,原因如下。
反射性能可能會比較低,畢竟是反正走的,一般比正向操作慢一兩個級別。
反射越多,代碼越爛,TypeOf和ValueOf都有Kind,很多情況是TypeOf和ValueOf混用的,所以對于基礎(chǔ)不好的,極不友好。
在Go中,是沒有try的,如果反射沒有處理好異常,程序會直接崩潰,可能在意想不到的地方。
以上就是Go語言中怎么實現(xiàn)結(jié)構(gòu)體反射,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。