久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      go語(yǔ)言有反射嗎

      go語(yǔ)言有反射。Go語(yǔ)言提供了一種機(jī)制在運(yùn)行時(shí)更新和檢查變量的值、調(diào)用變量的方法和變量支持的內(nèi)在操作,但是在編譯時(shí)并不知道這些變量的具體類(lèi)型,這種機(jī)制被稱(chēng)為反射。Go語(yǔ)言中的反射是由reflect包提供支持的,它定義了兩個(gè)重要的類(lèi)型Type和Value任意接口值在反射中都可以理解為由reflect.Type和reflect.Value兩部分組成。

      go語(yǔ)言有反射嗎

      php入門(mén)到就業(yè)線(xiàn)上直播課:進(jìn)入學(xué)習(xí)
      Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點(diǎn)擊使用

      本教程操作環(huán)境:windows7系統(tǒng)、GO 1.18版本、Dell G3電腦。

      Go語(yǔ)言提供了一種機(jī)制在運(yùn)行時(shí)更新和檢查變量的值、調(diào)用變量的方法和變量支持的內(nèi)在操作,但是在編譯時(shí)并不知道這些變量的具體類(lèi)型,這種機(jī)制被稱(chēng)為反射。反射也可以讓我們將類(lèi)型本身作為第一類(lèi)的值類(lèi)型處理。

      go語(yǔ)言中的反射

      反射是指在程序運(yùn)行期對(duì)程序本身進(jìn)行訪問(wèn)和修改的能力,程序在編譯時(shí)變量被轉(zhuǎn)換為內(nèi)存地址,變量名不會(huì)被編譯器寫(xiě)入到可執(zhí)行部分,在運(yùn)行程序時(shí)程序無(wú)法獲取自身的信息。

      支持反射的語(yǔ)言可以在程序編譯期將變量的反射信息,如字段名稱(chēng)、類(lèi)型信息、結(jié)構(gòu)體信息等整合到可執(zhí)行文件中,并給程序提供接口訪問(wèn)反射信息,這樣就可以在程序運(yùn)行期獲取類(lèi)型的反射信息,并且有能力修改它們。

      C/C++語(yǔ)言沒(méi)有支持反射功能,只能通過(guò) typeid 提供非常弱化的程序運(yùn)行時(shí)類(lèi)型信息;Java、C# 等語(yǔ)言都支持完整的反射功能;Lua、JavaScript 類(lèi)動(dòng)態(tài)語(yǔ)言,由于其本身的語(yǔ)法特性就可以讓代碼在運(yùn)行期訪問(wèn)程序自身的值和類(lèi)型信息,因此不需要反射系統(tǒng)。

      Go語(yǔ)言程序的反射系統(tǒng)無(wú)法獲取到一個(gè)可執(zhí)行文件空間中或者是一個(gè)包中的所有類(lèi)型信息,需要配合使用標(biāo)準(zhǔn)庫(kù)中對(duì)應(yīng)的詞法、語(yǔ)法解析器和抽象語(yǔ)法樹(shù)(AST)對(duì)源碼進(jìn)行掃描后獲得這些信息。

      Go語(yǔ)言提供了 reflect 包來(lái)訪問(wèn)程序的反射信息。

      reflect 包

      Go語(yǔ)言中的反射是由 reflect 包提供支持的,它定義了兩個(gè)重要的類(lèi)型 Type 和 Value 任意接口值在反射中都可以理解為由 reflect.Type 和 reflect.Value 兩部分組成,并且 reflect 包提供了 reflect.TypeOf 和 reflect.ValueOf 兩個(gè)函數(shù)來(lái)獲取任意對(duì)象的 Value 和 Type。

      反射的類(lèi)型對(duì)象(reflect.Type)

      在Go語(yǔ)言程序中,使用 reflect.TypeOf() 函數(shù)可以獲得任意值的類(lèi)型對(duì)象(reflect.Type),程序通過(guò)類(lèi)型對(duì)象可以訪問(wèn)任意值的類(lèi)型信息,下面通過(guò)示例來(lái)理解獲取類(lèi)型對(duì)象的過(guò)程:

      package main import (     "fmt"     "reflect" ) func main() {     var a int     typeOfA := reflect.TypeOf(a)     fmt.Println(typeOfA.Name(), typeOfA.Kind()) }
      登錄后復(fù)制

      運(yùn)行結(jié)果如下:

      go語(yǔ)言有反射嗎

      代碼說(shuō)明如下:

      • 第 9 行,定義一個(gè) int 類(lèi)型的變量。

      • 第 10 行,通過(guò) reflect.TypeOf() 取得變量 a 的類(lèi)型對(duì)象 typeOfA,類(lèi)型為 reflect.Type()。

      • 第 11 行中,通過(guò) typeOfA 類(lèi)型對(duì)象的成員函數(shù),可以分別獲取到 typeOfA 變量的類(lèi)型名為 int,種類(lèi)(Kind)為 int。

      反射的類(lèi)型(Type)與種類(lèi)(Kind)

      在使用反射時(shí),需要首先理解類(lèi)型(Type)和種類(lèi)(Kind)的區(qū)別。編程中,使用最多的是類(lèi)型,但在反射中,當(dāng)需要區(qū)分一個(gè)大品種的類(lèi)型時(shí),就會(huì)用到種類(lèi)(Kind)。例如需要統(tǒng)一判斷類(lèi)型中的指針時(shí),使用種類(lèi)(Kind)信息就較為方便。

      1) 反射種類(lèi)(Kind)的定義

      Go語(yǔ)言程序中的類(lèi)型(Type)指的是系統(tǒng)原生數(shù)據(jù)類(lèi)型,如 int、string、bool、float32 等類(lèi)型,以及使用 type 關(guān)鍵字定義的類(lèi)型,這些類(lèi)型的名稱(chēng)就是其類(lèi)型本身的名稱(chēng)。例如使用 type A struct{} 定義結(jié)構(gòu)體時(shí),A 就是 struct{} 的類(lèi)型。

      種類(lèi)(Kind)指的是對(duì)象歸屬的品種,在 reflect 包中有如下定義:

      type Kind uint const (     Invalid Kind = iota  // 非法類(lèi)型     Bool                 // 布爾型     Int                  // 有符號(hào)整型     Int8                 // 有符號(hào)8位整型     Int16                // 有符號(hào)16位整型     Int32                // 有符號(hào)32位整型     Int64                // 有符號(hào)64位整型     Uint                 // 無(wú)符號(hào)整型     Uint8                // 無(wú)符號(hào)8位整型     Uint16               // 無(wú)符號(hào)16位整型     Uint32               // 無(wú)符號(hào)32位整型     Uint64               // 無(wú)符號(hào)64位整型     Uintptr              // 指針     Float32              // 單精度浮點(diǎn)數(shù)     Float64              // 雙精度浮點(diǎn)數(shù)     Complex64            // 64位復(fù)數(shù)類(lèi)型     Complex128           // 128位復(fù)數(shù)類(lèi)型     Array                // 數(shù)組     Chan                 // 通道     Func                 // 函數(shù)     Interface            // 接口     Map                  // 映射     Ptr                  // 指針     Slice                // 切片     String               // 字符串     Struct               // 結(jié)構(gòu)體     UnsafePointer        // 底層指針 )
      登錄后復(fù)制

      Map、Slice、Chan 屬于引用類(lèi)型,使用起來(lái)類(lèi)似于指針,但是在種類(lèi)常量定義中仍然屬于獨(dú)立的種類(lèi),不屬于 Ptr。type A struct{} 定義的結(jié)構(gòu)體屬于 Struct 種類(lèi),*A 屬于 Ptr。

      2) 從類(lèi)型對(duì)象中獲取類(lèi)型名稱(chēng)和種類(lèi)

      Go語(yǔ)言中的類(lèi)型名稱(chēng)對(duì)應(yīng)的反射獲取方法是 reflect.Type 中的 Name() 方法,返回表示類(lèi)型名稱(chēng)的字符串;類(lèi)型歸屬的種類(lèi)(Kind)使用的是 reflect.Type 中的 Kind() 方法,返回 reflect.Kind 類(lèi)型的常量。

      下面的代碼中會(huì)對(duì)常量和結(jié)構(gòu)體進(jìn)行類(lèi)型信息獲取。

      package main import (     "fmt"     "reflect" ) // 定義一個(gè)Enum類(lèi)型 type Enum int const (     Zero Enum = 0 ) func main() {     // 聲明一個(gè)空結(jié)構(gòu)體     type cat struct {     }     // 獲取結(jié)構(gòu)體實(shí)例的反射類(lèi)型對(duì)象     typeOfCat := reflect.TypeOf(cat{})     // 顯示反射類(lèi)型對(duì)象的名稱(chēng)和種類(lèi)     fmt.Println(typeOfCat.Name(), typeOfCat.Kind())     // 獲取Zero常量的反射類(lèi)型對(duì)象     typeOfA := reflect.TypeOf(Zero)     // 顯示反射類(lèi)型對(duì)象的名稱(chēng)和種類(lèi)     fmt.Println(typeOfA.Name(), typeOfA.Kind()) }
      登錄后復(fù)制

      運(yùn)行結(jié)果如下:

      go語(yǔ)言有反射嗎

      代碼說(shuō)明如下:

      • 第 17 行,聲明結(jié)構(gòu)體類(lèi)型 cat。

      • 第 20 行,將 cat 實(shí)例化,并且使用 reflect.TypeOf() 獲取被實(shí)例化后的 cat 的反射類(lèi)型對(duì)象。

      • 第 22 行,輸出 cat 的類(lèi)型名稱(chēng)和種類(lèi),類(lèi)型名稱(chēng)就是 cat,而 cat 屬于一種結(jié)構(gòu)體種類(lèi),因此種類(lèi)為 struct。

      • 第 24 行,Zero 是一個(gè) Enum 類(lèi)型的常量。這個(gè) Enum 類(lèi)型在第 9 行聲明,第 12 行聲明了常量。如沒(méi)有常量也不能創(chuàng)建實(shí)例,通過(guò) reflect.TypeOf() 直接獲取反射類(lèi)型對(duì)象。

      • 第 26 行,輸出 Zero 對(duì)應(yīng)的類(lèi)型對(duì)象的類(lèi)型名和種類(lèi)。

      指針與指針指向的元素

      Go語(yǔ)言程序中對(duì)指針獲取反射對(duì)象時(shí),可以通過(guò) reflect.Elem() 方法獲取這個(gè)指針指向的元素類(lèi)型,這個(gè)獲取過(guò)程被稱(chēng)為取元素,等效于對(duì)指針類(lèi)型變量做了一個(gè)*操作,代碼如下:

      package main import (     "fmt"     "reflect" ) func main() {     // 聲明一個(gè)空結(jié)構(gòu)體     type cat struct {     }     // 創(chuàng)建cat的實(shí)例     ins := &cat{}     // 獲取結(jié)構(gòu)體實(shí)例的反射類(lèi)型對(duì)象     typeOfCat := reflect.TypeOf(ins)     // 顯示反射類(lèi)型對(duì)象的名稱(chēng)和種類(lèi)     fmt.Printf("name:'%v' kind:'%v'n", typeOfCat.Name(), typeOfCat.Kind())     // 取類(lèi)型的元素     typeOfCat = typeOfCat.Elem()     // 顯示反射類(lèi)型對(duì)象的名稱(chēng)和種類(lèi)     fmt.Printf("element name: '%v', element kind: '%v'n", typeOfCat.Name(), typeOfCat.Kind()) }
      登錄后復(fù)制

      運(yùn)行結(jié)果如下:

      go語(yǔ)言有反射嗎

      代碼說(shuō)明如下:

      • 第 13 行,創(chuàng)建了 cat 結(jié)構(gòu)體的實(shí)例,ins 是一個(gè) *cat 類(lèi)型的指針變量。

      • 第 15 行,對(duì)指針變量獲取反射類(lèi)型信息。

      • 第 17 行,輸出指針變量的類(lèi)型名稱(chēng)和種類(lèi)。Go語(yǔ)言的反射中對(duì)所有指針變量的種類(lèi)都是 Ptr,但需要注意的是,指針變量的類(lèi)型名稱(chēng)是空,不是 *cat。

      • 第 19 行,取指針類(lèi)型的元素類(lèi)型,也就是 cat 類(lèi)型。這個(gè)操作不可逆,不可以通過(guò)一個(gè)非指針類(lèi)型獲取它的指針類(lèi)型。

      • 第 21 行,輸出指針變量指向元素的類(lèi)型名稱(chēng)和種類(lèi),得到了 cat 的類(lèi)型名稱(chēng)(cat)和種類(lèi)(struct)。

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)