C語言中文網 目錄
首頁 > Go語言教程 > Go語言反射 閱讀:5,260

Go語言reflect.TypeOf()和reflect.Type(通過反射獲取類型信息)

在 Go 程序中,使用 reflect.TypeOf() 函數可以獲得任意值的類型對象(reflect.Type),程序通過類型對象可以訪問任意值的類型信息。下面通過例子來理解獲取類型對象的過程:
package main

import (
    "fmt"
    "reflect"
)

func main() {

    var a int

    typeOfA := reflect.TypeOf(a)

    fmt.Println(typeOfA.Name(), typeOfA.Kind())

}
代碼輸出如下:
int  int

代碼說明如下:
  • 第 10 行,定義一個 int 類型的變量。
  • 第 12 行,通過 reflect.TypeOf() 取得變量 a 的類型對象 typeOfA,類型為 reflect.Type()。
  • 第 14 行中,通過 typeOfA 類型對象的成員函數,可以分別獲取到 typeOfA 變量的類型名為 int,種類(Kind)為 int。

理解反射的類型(Type)與種類(Kind)

在使用反射時,需要首先理解類型(Type)和種類(Kind)的區別。編程中,使用最多的是類型,但在反射中,當需要區分一個大品種的類型時,就會用到種類(Kind)。例如,需要統一判斷類型中的指針時,使用種類(Kind)信息就較為方便。

1) 反射種類(Kind)的定義

Go 程序中的類型(Type)指的是系統原生數據類型,如 int、string、bool、float32 等類型,以及使用 type 關鍵字定義的類型,這些類型的名稱就是其類型本身的名稱。例如使用 type A struct{} 定義結構體時,A 就是 struct{} 的類型。

種類(Kind)指的是對象歸屬的品種,在 reflect 包中有如下定義:
type Kind uint

const (
    Invalid Kind = iota  // 非法類型
    Bool                 // 布爾型
    Int                  // 有符號整型
    Int8                 // 有符號8位整型
    Int16                // 有符號16位整型
    Int32                // 有符號32位整型
    Int64                // 有符號64位整型
    Uint                 // 無符號整型
    Uint8                // 無符號8位整型
    Uint16               // 無符號16位整型
    Uint32               // 無符號32位整型
    Uint64               // 無符號64位整型
    Uintptr              // 指針
    Float32              // 單精度浮點數
    Float64              // 雙精度浮點數
    Complex64            // 64位復數類型
    Complex128           // 128位復數類型
    Array                // 數組
    Chan                 // 通道
    Func                 // 函數
    Interface            // 接口
    Map                  // 映射
    Ptr                  // 指針
    Slice                // 切片
    String               // 字符串
    Struct               // 結構體
    UnsafePointer        // 底層指針
)
Map、Slice、Chan 屬于引用類型,使用起來類似于指針,但是在種類常量定義中仍然屬于獨立的種類,不屬于 Ptr。

type A struct{} 定義的結構體屬于 Struct 種類,*A 屬于 Ptr。

2) 從類型對象中獲取類型名稱和種類的例子

Go 語言中的類型名稱對應的反射獲取方法是 reflect.Type 中的 Name() 方法,返回表示類型名稱的字符串。

類型歸屬的種類(Kind)使用的是 reflect.Type 中的 Kind() 方法,返回 reflect.Kind 類型的常量。

下面的代碼中會對常量和結構體進行類型信息獲取。
package main

import (
    "fmt"
    "reflect"
)

// 定義一個Enum類型
type Enum int

const (
    Zero Enum = 0
)

func main() {

    // 聲明一個空結構體
    type cat struct {
    }

    // 獲取結構體實例的反射類型對象
    typeOfCat := reflect.TypeOf(cat{})

    // 顯示反射類型對象的名稱和種類
    fmt.Println(typeOfCat.Name(), typeOfCat.Kind())

    // 獲取Zero常量的反射類型對象
    typeOfA := reflect.TypeOf(Zero)

    // 顯示反射類型對象的名稱和種類
    fmt.Println(typeOfA.Name(), typeOfA.Kind())

}
代碼輸出如下:
cat struct
Enum int

代碼說明如下:
  • 第 18 行,聲明結構體類型 cat。
  • 第 22 行,將 cat 實例化,并且使用 reflect.TypeOf() 獲取被實例化后的 cat 的反射類型對象。
  • 第 25 行,輸出cat的類型名稱和種類,類型名稱就是 cat,而 cat 屬于一種結構體種類,因此種類為 struct。
  • 第 28 行,Zero 是一個 Enum 類型的常量。這個 Enum 類型在第 9 行聲明,第 12 行聲明了常量。如沒有常量也不能創建實例,通過 reflect.TypeOf() 直接獲取反射類型對象。
  • 第 31 行,輸出 Zero 對應的類型對象的類型名和種類。

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo