<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>

          一篇文章教會你Go語言基礎(chǔ)之反射

          共 3311字,需瀏覽 7分鐘

           ·

          2020-12-20 16:22

          點擊上方“Go語言進階學習”,進行關(guān)注

          回復“Go語言”即可獲贈從入門到進階共10本電子書

          四月南風大麥黃,棗花未落桐葉長。

          前言

          Hey,大家好呀,我是碼農(nóng),星期八!,我們以前學的呀,都屬于正向定義變量,正向開發(fā)!

          但是有沒有什么辦法能反著來呢?根據(jù)變量獲取類型等操作。

          一起來看看Go的反射吧!!!


          什么是反射

          反射,嗯...,就是反著的意思唄,就是把東西反過來。

          比如這樣的一個很簡單的代碼。

          var a int = 3fmt.Println(a)

          我們當然知道a變量是int類型,但是反過來想,程序是怎么知道aint類型呢???

          這時候,就需要用到反射了。

          示例代碼

          v := reflect.TypeOf(a)fmt.Println(v)

          兩次代碼綜合一塊執(zhí)行結(jié)果

          第二次的第2行代碼,成功的將變量a還原出了int類型。

          什么???你為我有什么用???,嗯。。。實話實說,用的不是太多,但是必須要會的。


          反射(reflect包)

          在Go中,任何變量,都有具體類型具體值,就像var a int = 3具體類型就是int具體值就是3

          所以,變量的具體類型歸屬在reflect.Type,變量的具體值歸屬在reflect.Value

          并且Go的提供了

          • reflect.TypeOf獲取具體類型

          • reflect.ValueOf獲取具體值

          TypeOf

          TypeOf方法可以獲取變量的具體類型

          有一個這樣的需求,定義一個函數(shù),可以接收任意類型數(shù)據(jù),通過反射打印變量類型。

          示例代碼

          函數(shù)

          func reflectType(x interface{}) {    v := reflect.TypeOf(x)    fmt.Printf("你傳入的變量類型是:%v\n",v)}

          main

          func main() {    var a int = 666    var b float64 = 3.14    var c string = "hello world"    var d [3]int = [3]int{126}    var e []int = []int{12688}    var f map[string]interface{} = map[string]interface{}{        "Name":"張三"        "Age":18}    reflectType(a)    reflectType(b)    reflectType(c)    reflectType(d)    reflectType(e)    reflectType(f)}

          執(zhí)行結(jié)果

          通過reflect.TypeOf方法,完美解決上述需求。

          TypeOf 的Name和Kind

          這個是啥意思呢??這個在結(jié)構(gòu)體中比較好體現(xiàn)。

          簡答來說就是TypeOf返回的太籠統(tǒng)了,還有更加細化的類型,通過這倆屬性獲取。

          示例代碼

          函數(shù)
          func reflectType(x interface{}) {v := reflect.TypeOf(x)fmt.Printf("你傳入的變量類型是:%v | Name:%v | Kind:%v\n", v, v.Name(), v.Kind())}
          結(jié)構(gòu)體
          type Student struct {    Name string    Age int}
          main
          func main() {    var a int    var b *int    var c []int    var d map[string]interface{}    var e Student    reflectType(a)    reflectType(b)    reflectType(c)    reflectType(d)    reflectType(e)}

          執(zhí)行結(jié)果

          總結(jié)

          經(jīng)過對比,會發(fā)現(xiàn)幾個特殊問題。

          如果變量是指針類型Name為空,Kindptr

          如果變量是引用類型(切片和map)類型,Name為空,只有Kind

          如果變量是結(jié)構(gòu)體Name是結(jié)構(gòu)體名,Kindstruct

          ValueOf

          TypeOf只能反過來獲取變量的具體類型,但是并不能獲取具體值,這就有點不太厚道了。

          所以ValueOf就來解決這個問題了,但是ValueOf牛叉的是,它里面還包括了變量類型

          注:ValueOfTypeOfKind屬性返回內(nèi)容是一摸一樣的。

          需求:定義一個函數(shù),可以接收任意類型,通過反射得出變量類型和變量值。

          函數(shù)

          func reflectType(x interface{}) {    v := reflect.ValueOf(x)    k := v.Kind()    switch k {    case reflect.Int:        fmt.Printf("我是Int類型,我的值是%v\n",v.Int())    case reflect.Slice:        fmt.Printf("我是切片類型,我的值是%v\n",v.Slice(1,2))    case reflect.Map:        fmt.Printf("我是切片類型,我的值是%v\n",v.MapKeys())    //case :可以繼續(xù)case下去  }}

          main

          func main() {  var a int = 1  var c []int = []int{15719}  var d map[string]interface{} = map[string]interface{}{    "Name": "你好"    "Age":  18  }  var e Student  reflectType(a)
          reflectType(c) reflectType(d) reflectType(e)}

          執(zhí)行結(jié)果

          通過反射設(shè)置值

          反射還有一個用途,就是動態(tài)的修改變量值,可能你暫時體會不到,但是語法還是要學的。

          通過反射設(shè)置值,需要用到Elem方法,并且傳入的必須是指針

          示例代碼

          函數(shù)

          func reflectSetValue(x interface{}) {  v := reflect.ValueOf(x)  //kind也必須是Elem調(diào)用  var k = v.Elem().Kind()  switch k {  case reflect.Int:    //反射修改必須通過Elem    v.Elem().SetInt(200)  }}

          main

          func main() {  var a int = 10  fmt.Printf("a的值:%v\n", a)  //反射修改值傳入的必須是地址  reflectSetValue(&a)  fmt.Printf("a的值:%v\n", a)}

          執(zhí)行結(jié)果

          總結(jié)

          上述我們學習了Go基礎(chǔ)反射的TypeOfTypeOf的Name和KindValueOf通過反射設(shè)置值

          其中KindTypeValueOf中都有,通常情況下TypeOfValueOf一起使用效果更佳!

          反射這一塊,可能不是那么好理解,一定要多多下功夫!堅持!!

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

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

          往期精彩文章推薦:

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

          想加入Go學習群請在后臺回復【入群

          萬水千山總是情,點個【在看】行不行

          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  色色色色综合 | 黑人巨大マラvs北条麻妃 | 色小姐噜噜久久 | 亚洲成人网在线免费观看 | 在线中文字幕av 中文字幕久久精品 |