偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

一篇帶給你Go語(yǔ)言的反射機(jī)制

開(kāi)發(fā) 后端
在計(jì)算機(jī)學(xué)中,反射式編程(英語(yǔ):reflective programming)或反射(英語(yǔ):reflection),是指計(jì)算機(jī)程序在運(yùn)行時(shí)(runtime)可以訪問(wèn)、檢測(cè)和修改它本身狀態(tài)或行為的一種能力。用比喻來(lái)說(shuō),反射就是程序在運(yùn)行的時(shí)候能夠“觀察”并且修改自己的行為。

因?yàn)闆](méi)有強(qiáng)類(lèi)型語(yǔ)言的經(jīng)驗(yàn),反射這個(gè)概念,之前確實(shí)沒(méi)怎么接觸過(guò)。在維基百科上搜了一下,具體解釋如下:

  • 在計(jì)算機(jī)學(xué)中,反射式編程(英語(yǔ):reflective programming)或反射(英語(yǔ):reflection),是指計(jì)算機(jī)程序在運(yùn)行時(shí)(runtime)可以訪問(wèn)、檢測(cè)和修改它本身狀態(tài)或行為的一種能力。用比喻來(lái)說(shuō),反射就是程序在運(yùn)行的時(shí)候能夠“觀察”并且修改自己的行為。

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

反射類(lèi)型

TypeOf 方法,會(huì)返回該變量的類(lèi)型對(duì)象,類(lèi)型對(duì)象下可以獲取到變量的類(lèi)型與種類(lèi)。

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

可以看到,此時(shí)的類(lèi)型與種類(lèi)都為 int。

類(lèi)型與種類(lèi)

類(lèi)型表示定義變量的時(shí)候指定的類(lèi)型,可以反映 type 關(guān)鍵字定義的類(lèi)型,而種類(lèi)是變量最終歸屬的類(lèi)型。說(shuō)起來(lái)可能比較蒼白,我們直接上代碼。

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

可以看到,此時(shí)的類(lèi)型為 num,種類(lèi)為 int。

對(duì)于一些引用類(lèi)型的變量,比如切片、函數(shù)、結(jié)構(gòu)體,kind 都能準(zhǔn)確反映其底層的類(lèi)型。

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

 

而面對(duì)匿名結(jié)構(gòu)體或者匿名函數(shù),其類(lèi)型值會(huì)返回為空。

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

 

反射值

ValueOf 方法,可以獲取一個(gè)變量的值。

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

 

通過(guò)反射的值對(duì)象,也能取到變量的種類(lèi),并且還能根據(jù)其種類(lèi),調(diào)用對(duì)應(yīng)的方法獲取變量的真實(shí)值。

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

 

修改值

通過(guò)反射得到的值對(duì)象,可以對(duì)變量本身的值進(jìn)行修改。首先,在獲取反射值時(shí),不能直接獲取變量的反射值,而是要先取其指針的值對(duì)象。

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

取出指針的值對(duì)象之后,不能立即賦值,因?yàn)榇藭r(shí)拿到的是變量的地址。

要賦值的話(huà),需要先調(diào)用 Elem 方法,取出具體元素,然后進(jìn)行賦值。

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

 

值對(duì)象與結(jié)構(gòu)體

前面介紹過(guò),通過(guò)反射可以得到變量的值,對(duì)于結(jié)構(gòu)體來(lái)說(shuō),也是一樣。

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

 

反射值對(duì)象還提供了一些方法,專(zhuān)門(mén)用來(lái)針對(duì)結(jié)構(gòu)體成員的信息獲取。

NumField()

NumField() 可以獲取結(jié)構(gòu)體成員的具體數(shù)量。

  1. var p = Person{"Shenfq", 25, "男""湖南長(zhǎng)沙"
  2. var v = reflect.ValueOf(p) 
  3.  
  4. fmt.Println("Person 結(jié)構(gòu)體成員數(shù):", v.NumField()) 

 

Field()

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

  1. var p = Person{"Shenfq", 25, "男""湖南長(zhǎng)沙"
  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() 可以獲取結(jié)構(gòu)體指定成員名稱(chēng)的成員的反射值。

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

 

- END -

責(zé)任編輯:姜華 來(lái)源: 自然醒的筆記本
相關(guān)推薦

2021-06-24 06:35:00

Go語(yǔ)言進(jìn)程

2021-04-09 10:38:59

Go 語(yǔ)言數(shù)組與切片

2021-04-06 10:19:36

Go語(yǔ)言基礎(chǔ)技術(shù)

2021-04-01 10:51:55

MySQL鎖機(jī)制數(shù)據(jù)庫(kù)

2021-04-20 06:12:09

Swift 反射 Mirror反射機(jī)制

2021-03-24 06:06:13

Go并發(fā)編程Singlefligh

2021-07-12 06:11:14

SkyWalking 儀表板UI篇

2021-06-21 14:36:46

Vite 前端工程化工具

2021-01-28 08:55:48

Elasticsear數(shù)據(jù)庫(kù)數(shù)據(jù)存儲(chǔ)

2023-03-29 07:45:58

VS編輯區(qū)編程工具

2021-04-14 14:16:58

HttpHttp協(xié)議網(wǎng)絡(luò)協(xié)議

2021-04-08 11:00:56

CountDownLaJava進(jìn)階開(kāi)發(fā)

2021-07-21 09:48:20

etcd-wal模塊解析數(shù)據(jù)庫(kù)

2024-06-13 08:34:48

2022-03-22 09:09:17

HookReact前端

2022-04-29 14:38:49

class文件結(jié)構(gòu)分析

2021-03-12 09:21:31

MySQL數(shù)據(jù)庫(kù)邏輯架構(gòu)

2022-02-17 08:53:38

ElasticSea集群部署

2022-02-25 15:50:05

OpenHarmonToggle組件鴻蒙

2021-04-23 08:59:35

ClickHouse集群搭建數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)