成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一篇帶給你Go語言的反射機制

開發 后端
在計算機學中,反射式編程(英語:reflective programming)或反射(英語:reflection),是指計算機程序在運行時(runtime)可以訪問、檢測和修改它本身狀態或行為的一種能力。用比喻來說,反射就是程序在運行的時候能夠“觀察”并且修改自己的行為。

因為沒有強類型語言的經驗,反射這個概念,之前確實沒怎么接觸過。在維基百科上搜了一下,具體解釋如下:

  • 在計算機學中,反射式編程(英語:reflective programming)或反射(英語:reflection),是指計算機程序在運行時(runtime)可以訪問、檢測和修改它本身狀態或行為的一種能力。用比喻來說,反射就是程序在運行的時候能夠“觀察”并且修改自己的行為。

go 中的反射也是這種作用,可以在程序運行期間,獲取變量的類型與值的信息,然后進行訪問或或者修改。go 語言中,內置了 reflect 包,用來獲取一個變量的類型(type)與值(value),對應的方法分別為 reflect.TypeOf() 和 reflect.ValueOf()。

反射類型

TypeOf 方法,會返回該變量的類型對象,類型對象下可以獲取到變量的類型與種類。

  1. import ( 
  2.  "fmt" 
  3.  "reflect" 
  4.  
  5. func main() { 
  6.  // 定義一個int類型的變量 
  7.  var i int = 1 
  8.  // 獲取變量的類型對象 
  9.  var typeOfNum = reflect.TypeOf(i)  
  10.  
  11.   // 輸出類型與種類 
  12.   typeOfNumName = typeOfNum.Name() 
  13.   typeOfNumKind = typeOfNum.Kind() 
  14.   fmt.Printf("name: %s, kind: %s", typeOfNumName, typeOfNumKind) 

可以看到,此時的類型與種類都為 int。

類型與種類

類型表示定義變量的時候指定的類型,可以反映 type 關鍵字定義的類型,而種類是變量最終歸屬的類型。說起來可能比較蒼白,我們直接上代碼。

  1. type num int 
  2.  
  3. // 定義一個num類型的變量 
  4. var i num = 1 
  5. var typeOfNum = reflect.TypeOf(i)  

可以看到,此時的類型為 num,種類為 int。

對于一些引用類型的變量,比如切片、函數、結構體,kind 都能準確反映其底層的類型。

  1. func printTypeOf(typeOf reflect.Type) { 
  2.  fmt.Printf("name: %s, kind: %s\n", typeOf.Name(), typeOf.Kind()) 
  3.  
  4. type Person struct {} 
  5. type IntSlice []int 
  6. func main() { 
  7.  var a = IntSlice{} 
  8.  var b = Person{} 
  9.  printTypeOf(reflect.TypeOf(a)) 
  10.  printTypeOf(reflect.TypeOf(b)) 

 

而面對匿名結構體或者匿名函數,其類型值會返回為空。

  1. func main() { 
  2.  var a = struct {}{} 
  3.  printTypeOf(reflect.TypeOf(a)) 

 

反射值

ValueOf 方法,可以獲取一個變量的值。

  1. var i = 3.1415926 
  2. var s = "歡迎關注我的公眾號:『自然醒的筆記本』" 
  3.  
  4. fmt.Println(reflect.ValueOf(s)) 
  5. fmt.Println(reflect.ValueOf(i)) 

 

通過反射的值對象,也能取到變量的種類,并且還能根據其種類,調用對應的方法獲取變量的真實值。

  1. var i = 100 
  2. var v = reflect.ValueOf(i) 
  3.  
  4. fmt.Println(v.Int()) // 如果值是 Int 類型,可以通過 Int 方法獲取具體值 
  5. fmt.Println(v.Kind()) 

 

修改值

通過反射得到的值對象,可以對變量本身的值進行修改。首先,在獲取反射值時,不能直接獲取變量的反射值,而是要先取其指針的值對象。

  1. var i = 100 
  2. var v = reflect.ValueOf(&i) // 取出變量i的指針的值對象 
  3.  
  4. fmt.Println(v.Kind(), v) 

取出指針的值對象之后,不能立即賦值,因為此時拿到的是變量的地址。

要賦值的話,需要先調用 Elem 方法,取出具體元素,然后進行賦值。

  1. var i = 100 
  2. var v = reflect.ValueOf(&i) // 取出變量i的指針的值對象 
  3.  
  4. var e = v.Elem() 
  5. e.SetInt(500) // 修改元素值 
  6.  
  7. fmt.Println(e.Kind(), i) 

 

值對象與結構體

前面介紹過,通過反射可以得到變量的值,對于結構體來說,也是一樣。

  1. type Person struct { 
  2.  name string 
  3.  age int 
  4.  gender string 
  5.  address string 
  6.  
  7. var p = Person{"Shenfq", 25, "男""湖南長沙"
  8. var v = reflect.ValueOf(p) 
  9.  
  10. fmt.Println(v.Kind(), v) 

 

反射值對象還提供了一些方法,專門用來針對結構體成員的信息獲取。

NumField()

NumField() 可以獲取結構體成員的具體數量。

  1. var p = Person{"Shenfq", 25, "男""湖南長沙"
  2. var v = reflect.ValueOf(p) 
  3.  
  4. fmt.Println("Person 結構體成員數:", v.NumField()) 

 

Field()

Field() 可以獲取結構體指定索引位置的成員的反射值。

  1. var p = Person{"Shenfq", 25, "男""湖南長沙"
  2. var v = reflect.ValueOf(p) 
  3. var num = v.NumField() 
  4. for i :=0; i < num; i++ { 
  5.   var val = v.Field(i) 
  6.   fmt.Printf("Person[%d]: %s %v\n", i, val.Type(), val) 

 

FieldByName()

FieldByName() 可以獲取結構體指定成員名稱的成員的反射值。

  1. var p = Person{"Shenfq", 25, "男""湖南長沙"
  2. var v = reflect.ValueOf(p) 
  3. var vOfName = v.FieldByName("name"
  4. fmt.Printf("Person[name]: %s %v\n", vOfName.Type(), vOfName) 

 

- END -

責任編輯:姜華 來源: 自然醒的筆記本
相關推薦

2021-06-24 06:35:00

Go語言進程

2021-04-09 10:38:59

Go 語言數組與切片

2021-04-06 10:19:36

Go語言基礎技術

2021-04-01 10:51:55

MySQL鎖機制數據庫

2021-04-20 06:12:09

Swift 反射 Mirror反射機制

2021-03-24 06:06:13

Go并發編程Singlefligh

2021-07-12 06:11:14

SkyWalking 儀表板UI篇

2021-06-21 14:36:46

Vite 前端工程化工具

2021-01-28 08:55:48

Elasticsear數據庫數據存儲

2023-03-29 07:45:58

VS編輯區編程工具

2021-04-14 14:16:58

HttpHttp協議網絡協議

2021-04-08 11:00:56

CountDownLaJava進階開發

2022-03-22 09:09:17

HookReact前端

2021-07-21 09:48:20

etcd-wal模塊解析數據庫

2021-03-12 09:21:31

MySQL數據庫邏輯架構

2022-02-17 08:53:38

ElasticSea集群部署

2022-04-29 14:38:49

class文件結構分析

2024-06-13 08:34:48

2022-02-25 15:50:05

OpenHarmonToggle組件鴻蒙

2021-10-28 08:51:53

GPIO軟件框架 Linux
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: www.youjizz.com日韩 | 久久久国 | 精品欧美| 男人影音 | 久久精品成人热国产成 | 午夜精品福利视频 | 午夜精品一区二区三区免费视频 | 中文字幕观看 | 超碰在线播 | 一区二区三区久久久 | av片在线播放 | 成人视屏在线观看 | 国产一区二区在线播放 | 日韩www| 99视频在线播放 | 四季久久免费一区二区三区四区 | 在线看91 | 国产精品美女久久久 | 亚洲视频一区二区三区 | 亚洲av一级毛片 | 国产精品爱久久久久久久 | 一区在线播放 | 久久99精品久久久久久青青日本 | 国产午夜视频 | 久久在线| 久久精品在线免费视频 | 91成人免费电影 | 日美女逼逼 | 中文字幕在线国产 | 欧美性久久| 国产午夜亚洲精品不卡 | 欧洲成人| 亚洲色综合 | 日韩在线一区二区三区 | 国产一区二区三区在线看 | 久久久久久高潮国产精品视 | 中文字幕在线观看第一页 | 国产一区二区免费电影 | 国产玖玖 | 亚洲成人一区二区三区 | 亚洲成人自拍 |