<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一篇文章教會(huì)你Go語言基礎(chǔ)之結(jié)構(gòu)體反射

          共 4530字,需瀏覽 10分鐘

           ·

          2020-12-20 16:22

          點(diǎn)擊上方“Go語言進(jìn)階學(xué)習(xí)”,進(jìn)行關(guān)注

          回復(fù)“Go語言”即可獲贈(zèng)從入門到進(jìn)階共10本電子書

          四月南風(fēng)大麥黃,棗花未落桐葉長(zhǎng)。

          前言

          Hey,大家好呀,我是碼農(nóng),星期八。

          反射在結(jié)構(gòu)體中的應(yīng)用,才是最廣泛的!畢竟在Go中,是用結(jié)構(gòu)體代替對(duì)象的!

          所以最多的,最麻煩的,也是反射結(jié)構(gòu)體,也是最靈活的!


          反射在結(jié)構(gòu)體的應(yīng)用

          上次講的,只是在普通變量中的應(yīng)用,相對(duì)來說,使用的場(chǎng)景不是太多。

          但是反射在結(jié)構(gòu)體中的應(yīng)用,基本會(huì)貫穿整個(gè)Go語言基礎(chǔ)。

          示例代碼

          結(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() {    //實(shí)例化結(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,表示多少個(gè)字段    for i := 0; i < t.NumField(); i++ {        field := t.Field(i)//每個(gè)結(jié)構(gòu)體對(duì)象        /*            {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() {    //實(shí)例化結(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,只能返回類型等信息,相對(duì)來說不是太智能,ValueOf可以獲取值,同樣也能獲取類型,相對(duì)來說比TypeOf好一點(diǎn)。

          示例代碼

          main

          func main() {    //實(shí)例化結(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() {    //實(shí)例化結(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() {    //實(shí)例化結(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ù)必須傳一個(gè)參數(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é)果


          反射注意事項(xiàng)

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

          • 反射性能可能會(huì)比較低,畢竟是反正走的,一般比正向操作慢一兩個(gè)級(jí)別。

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

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

          總結(jié)

          上述我們主要講述了Go反射結(jié)構(gòu)體相關(guān)知識(shí),包括有

          • 反射在結(jié)構(gòu)體中的應(yīng)用

          • 如何單獨(dú)反射結(jié)構(gòu)體字段信息

          • ValueOf其他操作

          • 如何放射結(jié)構(gòu)體綁定的方法

          到此為止反射就講完了,一定要多嘗試,多敲敲代碼,反射的用法還有很多。

          如果在操作過程中有任何問題,記得下面留言,我們看到會(huì)第一時(shí)間解決問題。我是碼農(nóng)星期八,如果覺得還不錯(cuò),記得動(dòng)手點(diǎn)贊一下哈。感謝你的觀看。

          想了解更多關(guān)于Go的知識(shí),請(qǐng)前往:http://pdcfighting.com/

          -------------------?End?-------------------

          往期精彩文章推薦:

          歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持

          想加入Go學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群

          萬水千山總是情,點(diǎn)個(gè)【在看】行不行

          瀏覽 31
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  深爱五月丁香婷婷 | 精品免费一区二区三区在线赤裸 | 亲子乱aⅴ一区二区三区的 | 亚洲性爱片 | 久久久噜噜噜久久中文字幕色伊伊 |