golang的reflection(轉)(一)

反射reflection

  • 能夠大大提升程序的靈活性,使得interface{}有更大的發揮餘地
  • 反射能夠使用TypeOf和ValueOf函數從接口中獲取目標對象信息
  • 反射會將匿名字段做爲獨立字段(匿名字段的本質)
  • 想要利用反射修改對象狀態,前提是interface.data是settable,即pointer-interface
  • 經過反射能夠「動態」調用方法

經常使用的類型、函數和方法

//返回動態類型i的類型,若是i是一個空結構體類型,TypeOf將返回nil
func TypeOf(i interface{}) Type

//Type 接口類型
type Type interface {
    Align() int
    FieldAlign() int
    //指定結構體中方法的下標,返回某個方法的對象,須要注意的是返回的Method是一個獨立的結構體
    Method(int) Method
    /*
    type Method struct {
        Name string
        PkgPath string
        Type Type
        Func Value
        Index int
    }
    */


    MethodByName(string) (Method, bool)

    //返回該結構體類型的方法下標
    NumMethod() int
    //返回類型的名稱,即動態類型i的名稱
    Name() string
    PkgPath() string
    Size() uintptr
    String() string
    Kind() Kind
    Implements(u Type) bool
    AssignableTo(u Type) bool
    ConvertibleTo(u Type) bool
    Comparable() bool
    Bits() int
    ChanDir() ChanDir
    IsVariadic() bool
    Elem() Type
    //返回結構體類型第i個字段
    Field(i int) StructField
    //StructField結構體
    //type StructField struct {
    // Name string
    // PkgPath string
    // Type Type
    // Tag  StructTag
    // Offset uintptr
    // Index []int
    // Anonymous bool

    //根據結構體字段索引獲取嵌入字段的結構體信息
    FieldByIndex(index []int) StructField

    FieldByName(name string) (StructField, bool)
    FieldByNameFunc(match func(string) bool) (StructField, bool)
    In(i int) Type
    Key() Type
    Len() int
    //返回動態類型i(結構體字段)的字段總數
    NumField() int
    NumIn() int
    NumOut() int
    Out(i int) Type
}

//返回接口i的一個初始化的新值.ValueOf(nil)返回一個零值
func ValueOf(i interface{}) Value

// Value結構體
type Value struct {

}
// Value結構體的一些方法
// 返回結構體v中的第i個字段。若是v的類型不是結構體或者i超出告終構體的範圍,則會出現panic
func (v Value) Field(i int) Value

//以接口類型返回v的當前值
func (v Value) Interface() (i interface{})
//等價於.
var i interface{} = (v's underlying value)


//經過反射方式修改結構體對象的一些方法

//返回接口v包含或者指針v包含的值
func (v Value) Elem() Value
//判斷該接口v是否能夠被set修改
func (v Value) CanSet() bool

//使用另一個反射接口去修改反射值
func (v Value) Set(x Value)
//其餘不一樣類型的Set
func (v Value) SetBool(x bool)
func (v Value) SetBytes(x []byte)
func (v Value) SetFloat(x float64)
func (v Value) SetInt(x int64)
//設置結構體對象v的長度爲n
func (v Value) SetLen(n int)
func (v Value) SetString(x string)


//一些輔助方法
//返回反射結構體的Value的類型.若是v爲零值,IsValid將返回false
func (v Value) Kind() Kind
//判斷value是否爲有效值,一般用在判斷某個字段是否在反射體的Value中
func (v Value) IsValid() bool

//Kind常量
type Kind uint
const (
        Invalid Kind = iota
        Bool
        Int
        Int8
        Int16
        Int32
        Int64
        Uint
        Uint8
        Uint16
        Uint32
        Uint64
        Uintptr
        Float32
        Float64
        Complex64
        Complex128
        Array
        Chan
        Func
        Interface
        Map
        Ptr
        Slice
        String
        Struct
        UnsafePointer
)

 

反射的基本操做

經過反射來獲取結構體字段的名稱以及其餘相關信息。函數

package main import ( "fmt" "reflect" ) //定義結構體 type User struct { Id int Name string Age int } //定義結構體方法 func (u User) Hello() { fmt.Println("Hello xuxuebiao") } func main() { u := User{1, "bgops", 25} Info(u) u.Hello() } //定義一個反射函數,參數爲任意類型 func Info(o interface{}) { //使用反射類型獲取o的Type,一個包含多個方法的interface t := reflect.TypeOf(o) //打印類型o的名稱 fmt.Println("type:", t.Name()) //使用反射類型獲取o的Value,一個空的結構體 v := reflect.ValueOf(o) fmt.Println("Fields:") //t.NumField()打印結構體o的字段個數(Id,Name,Age共三個) for i := 0; i < t.NumField(); i++ { //根據結構體的下標i來獲取結構體某個字段,並返回一個新的結構體 /** type StructField struct { Name string PkgPath string Type Type Tag StructTag Of
相關文章
相關標籤/搜索