溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Go語言中怎么實現(xiàn)結(jié)構(gòu)體反射

發(fā)布時間:2021-07-06 16:02:04 來源:億速云 閱讀:146 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關(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é)果

Go語言中怎么實現(xiàn)結(jié)構(gòu)體反射

單獨(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é)果

 Go語言中怎么實現(xiàn)結(jié)構(gòu)體反射

反射方法

上述我們反射的都是值,有沒有反射是否可以反射函數(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é)果

 Go語言中怎么實現(xiàn)結(jié)構(gòu)體反射

反射調(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é)果

Go語言中怎么實現(xiàn)結(jié)構(gòu)體反射

反射注意事項

在平常開發(fā)中,盡量慎用反射,原因如下。

  • 反射性能可能會比較低,畢竟是反正走的,一般比正向操作慢一兩個級別。

  • 反射越多,代碼越爛,TypeOf和ValueOf都有Kind,很多情況是TypeOf和ValueOf混用的,所以對于基礎(chǔ)不好的,極不友好。

  • 在Go中,是沒有try的,如果反射沒有處理好異常,程序會直接崩潰,可能在意想不到的地方。

以上就是Go語言中怎么實現(xiàn)結(jié)構(gòu)體反射,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(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)容。

AI