日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
一篇文章教會(huì)你Go語(yǔ)言基礎(chǔ)之反射

前言

在朗縣等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站制作、網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作定制設(shè)計(jì),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,營(yíng)銷型網(wǎng)站建設(shè),成都外貿(mào)網(wǎng)站建設(shè),朗縣網(wǎng)站建設(shè)費(fèi)用合理。

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

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

一起來(lái)看看Go的反射吧!!!

什么是反射

反射,嗯...,就是反著的意思唄,就是把東西反過(guò)來(lái)。

比如這樣的一個(gè)很簡(jiǎn)單的代碼。

 
 
 
 
  1. var a int = 3 
  2. fmt.Println(a) 

我們當(dāng)然知道a變量是int類型,但是反過(guò)來(lái)想,程序是怎么知道a是int類型呢???

這時(shí)候,就需要用到反射了。

示例代碼

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

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

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

什么???你為我有什么用???,嗯。。。實(shí)話實(shí)說(shuō),用的不是太多,但是必須要會(huì)的。

反射(reflect包)

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

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

并且Go的提供了

  • reflect.TypeOf獲取具體類型。
  • reflect.ValueOf獲取具體值。

TypeOf

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

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

示例代碼

函數(shù)

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

main

 
 
 
 
  1. func main() { 
  2.     var a int = 666 
  3.     var b float64 = 3.14 
  4.     var c string = "hello world" 
  5.     var d [3]int = [3]int{1,2,6} 
  6.     var e []int = []int{1,2,6,88} 
  7.     var f map[string]interface{} = map[string]interface{}{ 
  8.         "Name":"張三", 
  9.         "Age":18, 
  10.     reflectType(a) 
  11.     reflectType(b) 
  12.     reflectType(c) 
  13.     reflectType(d) 
  14.     reflectType(e) 
  15.     reflectType(f) 

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

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

TypeOf 的Name和Kind

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

簡(jiǎn)答來(lái)說(shuō)就是TypeOf返回的太籠統(tǒng)了,還有更加細(xì)化的類型,通過(guò)這倆屬性獲取。

示例代碼

函數(shù)

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

結(jié)構(gòu)體

 
 
 
 
  1. type Student struct { 
  2.     Name string 
  3.     Age int 

main

 
 
 
 
  1. func main() { 
  2.     var a int 
  3.     var b *int 
  4.     var c []int 
  5.     var d map[string]interface{} 
  6.     var e Student 
  7.     reflectType(a) 
  8.     reflectType(b) 
  9.     reflectType(c) 
  10.     reflectType(d) 
  11.     reflectType(e) 

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

總結(jié)

經(jīng)過(guò)對(duì)比,會(huì)發(fā)現(xiàn)幾個(gè)特殊問題。

如果變量是指針類型,Name為空,Kind是ptr。

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

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

ValueOf

TypeOf只能反過(guò)來(lái)獲取變量的具體類型,但是并不能獲取具體值,這就有點(diǎn)不太厚道了。

所以ValueOf就來(lái)解決這個(gè)問題了,但是ValueOf牛叉的是,它里面還包括了變量類型。

注:ValueOf和TypeOf的Kind屬性返回內(nèi)容是一摸一樣的。

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

函數(shù)

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

main

 
 
 
 
  1. func main() { 
  2.   var a int = 1 
  3.   var c []int = []int{1, 5, 7, 19} 
  4.   var d map[string]interface{} = map[string]interface{}{ 
  5.     "Name": "你好", 
  6.     "Age":  18, 
  7.   } 
  8.   var e Student 
  9.   reflectType(a) 
  10.  
  11.   reflectType(c) 
  12.   reflectType(d) 
  13.   reflectType(e) 

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

通過(guò)反射設(shè)置值

反射還有一個(gè)用途,就是動(dòng)態(tài)的修改變量值,可能你暫時(shí)體會(huì)不到,但是語(yǔ)法還是要學(xué)的。

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

示例代碼

函數(shù)

 
 
 
 
  1. func reflectSetValue(x interface{}) { 
  2.   v := reflect.ValueOf(x) 
  3.   //kind也必須是Elem調(diào)用 
  4.   var k = v.Elem().Kind() 
  5.   switch k { 
  6.   case reflect.Int: 
  7.     //反射修改必須通過(guò)Elem 
  8.     v.Elem().SetInt(200) 
  9.   } 

main

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

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

總結(jié)

上述我們學(xué)習(xí)了Go基礎(chǔ)反射的TypeOf,TypeOf的Name和Kind,ValueOf,通過(guò)反射設(shè)置值。

其中Kind在Type和ValueOf中都有,通常情況下TypeOf和ValueOf一起使用效果更佳!

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

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

本文轉(zhuǎn)載自微信公眾號(hào)「Go語(yǔ)言進(jìn)階學(xué)習(xí)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Go語(yǔ)言進(jìn)階學(xué)習(xí)公眾號(hào)。


本文名稱:一篇文章教會(huì)你Go語(yǔ)言基礎(chǔ)之反射
網(wǎng)址分享:http://m.5511xx.com/article/djphpcg.html