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
相关文章
相关标签/搜索