Golang标准库——reflect

DevilRoshan · · 523 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

reflect

reflect包实现了运行时反射,允许程序操作任意类型的对象。典型用法是用静态类型interface{}保存一个值,通过调用TypeOf获取其动态类型信息,该函数返回一个Type类型值。调用ValueOf函数返回一个Value类型值,该值代表运行时的数据。Zero接受一个Type类型参数并返回一个代表该类型零值的Value类型值。

参见"The Laws of Reflection"获取go反射的介绍:http://golang.org/doc/articles/laws_of_reflection.html

Constants

const (
    SelectSend    // case Chan <- Send
    SelectRecv    // case <-Chan:
    SelectDefault // default
)

type ValueError

type ValueError struct {
    Method string
    Kind   Kind
}

当一个Value类型值调用它不支持的方法时,将导致ValueError。具体情况参见各个方法。

func (*ValueError) Error

func (e *ValueError) Error() string

type Kind

type Kind uint

Kind代表Type类型值表示的具体分类。零值表示非法分类。

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
)

func (Kind) String

func (k Kind) String() string

type StringHeader

type StringHeader struct {
    Data uintptr
    Len  int
}

StringHeader代表一个运行时的字符串。它不保证使用的可移植性、安全性;它的实现在未来的版本里也可能会改变。而且,Data字段也不能保证它指向的数据不会被当成垃圾收集,因此程序必须维护一个独立的、类型正确的指向底层数据的指针。

type SliceHeader

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

SliceHeader代表一个运行时的切片。它不保证使用的可移植性、安全性;它的实现在未来的版本里也可能会改变。而且,Data字段也不能保证它指向的数据不会被当成垃圾收集,因此程序必须维护一个独立的、类型正确的指向底层数据的指针。

type StructField

type StructField struct {
    // Name是字段的名字。PkgPath是非导出字段的包路径,对导出字段该字段为""。
    // 参见http://golang.org/ref/spec#Uniqueness_of_identifiers
    Name    string
    PkgPath string
    Type      Type      // 字段的类型
    Tag       StructTag // 字段的标签
    Offset    uintptr   // 字段在结构体中的字节偏移量
    Index     []int     // 用于Type.FieldByIndex时的索引切片
    Anonymous bool      // 是否匿名字段
}

StructField类型描述结构体中的一个字段的信息。

type StructTag

type StructTag string

StructTag是结构体字段的标签。

一般来说,标签字符串是(可选的)空格分隔的一连串key:"value"对。每个键都是不包含控制字符、空格、双引号、冒号的非空字符串。每个值都应被双引号括起来,使用go字符串字面语法。

type S struct {
    F string `species:"gopher" color:"blue"`
}
s := S{}
st := reflect.TypeOf(s)
field := st.Field(0)
fmt.Println(field.Tag.Get("color"), field.Tag.Get("species"))
// blue gopher

func (StructTag) Get

func (tag StructTag) Get(key string) string

Get方法返回标签字符串中键key对应的值。如果标签中没有该键,会返回""。如果标签不符合标准格式,Get的返回值是不确定的。

type ChanDir

type ChanDir int

ChanDir表示通道类型的方向。

const (
    RecvDir ChanDir             = 1 << iota // <-chan
    SendDir                                 // chan<-
    BothDir = RecvDir | SendDir             // chan
)

func (ChanDir) String

func (d ChanDir) String() string

type SelectDir

type SelectDir int

SelectDir描述一个SelectCase的通信方向。

type SelectCase

type SelectCase struct {
    Dir  SelectDir // case的方向
    Chan Value     // 使用的通道(收/发)
    Send Value     // 用于发送的值
}

SelectCase描述select操作中的单条case。Case的类型由通信方向Dir决定。

如果Dir是SelectDefault,该条case代表default case。Chan和Send字段必须是Value零值。

如果Dir是SelectSend,该条case代表一个发送操作。Chan字段底层必须是一个chan类型,Send的底层必须是可以直接赋值给该chan类型成员类型的类型。如果Chan是Value零值,则不管Send字段是不是零值,该条case都会被忽略。

如果Dir是SelectRecv,该条case代表一个接收操作。Chan字段底层必须是一个chan类型,而Send必须是一个Value零值。如果Chan是Value零值,该条case会被忽略,但Send字段仍需是Value零值。当该条case被执行时,接收到的值会被Select返回。

func Select

func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool)

Select函数执行cases切片描述的select操作。 类似go的select语句,它会阻塞直到至少一条case可以执行,从可执行的case中(伪)随机的选择一条,并执行该条case。它会返回选择执行的case的索引,以及如果执行的是接收case时,会返回接收到的值,以及一个布尔值说明该值是否对应于通道中某次发送的值(用以区分通道关闭时接收到的零值,此时recvOK会设为false)。

type Method

type Method struct {
    // Name是方法名。PkgPath是非导出字段的包路径,对导出字段该字段为""。
    // 结合PkgPath和Name可以从方法集中指定一个方法。
    // 参见http://golang.org/ref/spec#Uniqueness_of_identifiers
    Name    string
    PkgPath string
    Type  Type  // 方法类型
    Func  Value // 方法的值
    Index int   // 用于Type.Method的索引
}

Method代表一个方法。

type Type

type Type interface {
    // Kind返回该接口的具体分类
    Kind() Kind
    // Name返回该类型在自身包内的类型名,如果是未命名类型会返回""
    Name() string
    // PkgPath返回类型的包路径,即明确指定包的import路径,如"encoding/base64"
    // 如果类型为内建类型(string, error)或未命名类型(*T, struct{}, []int),会返回""
    PkgPath() string
    // 返回类型的字符串表示。该字符串可能会使用短包名(如用base64代替"encoding/base64")
    // 也不保证每个类型的字符串表示不同。如果要比较两个类型是否相等,请直接用Type类型比较。
    String() string
    // 返回要保存一个该类型的值需要多少字节;类似unsafe.Sizeof
    Size() uintptr
    // 返回当从内存中申请一个该类型值时,会对齐的字节数
    Align() int
    // 返回当该类型作为结构体的字段时,会对齐的字节数
    FieldAlign() int
    // 如果该类型实现了u代表的接口,会返回真
    Implements(u Type) bool
    // 如果该类型的值可以直接赋值给u代表的类型,返回真
    AssignableTo(u Type) bool
    // 如该类型的值可以转换为u代表的类型,返回真
    ConvertibleTo(u Type) bool
    // 返回该类型的字位数。如果该类型的Kind不是Int、Uint、Float或Complex,会panic
    Bits() int
    // 返回array类型的长度,如非数组类型将panic
    Len() int
    // 返回该类型的元素类型,如果该类型的Kind不是Array、Chan、Map、Ptr或Slice,会panic
    Elem() Type
    // 返回map类型的键的类型。如非映射类型将panic
    Key() Type
    // 返回一个channel类型的方向,如非通道类型将会panic
    ChanDir() ChanDir
    // 返回struct类型的字段数(匿名字段算作一个字段),如非结构体类型将panic
    NumField() int
    // 返回struct类型的第i个字段的类型,如非结构体或者i不在[0, NumField())内将会panic
    Field(i int) StructField
    // 返回索引序列指定的嵌套字段的类型,
    // 等价于用索引中每个值链式调用本方法,如非结构体将会panic
    FieldByIndex(index []int) StructField
    // 返回该类型名为name的字段(会查找匿名字段及其子字段),
    // 布尔值说明是否找到,如非结构体将panic
    FieldByName(name string) (StructField, bool)
    // 返回该类型第一个字段名满足函数match的字段,布尔值说明是否找到,如非结构体将会panic
    FieldByNameFunc(match func(string) bool) (StructField, bool)
    // 如果函数类型的最后一个输入参数是"..."形式的参数,IsVariadic返回真
    // 如果这样,t.In(t.NumIn() - 1)返回参数的隐式的实际类型(声明类型的切片)
    // 如非函数类型将panic
    IsVariadic() bool
    // 返回func类型的参数个数,如果不是函数,将会panic
    NumIn() int
    // 返回func类型的第i个参数的类型,如非函数或者i不在[0, NumIn())内将会panic
    In(i int) Type
    // 返回func类型的返回值个数,如果不是函数,将会panic
    NumOut() int
    // 返回func类型的第i个返回值的类型,如非函数或者i不在[0, NumOut())内将会panic
    Out(i int) Type
    // 返回该类型的方法集中方法的数目
    // 匿名字段的方法会被计算;主体类型的方法会屏蔽匿名字段的同名方法;
    // 匿名字段导致的歧义方法会滤除
    NumMethod() int
    // 返回该类型方法集中的第i个方法,i不在[0, NumMethod())范围内时,将导致panic
    // 对非接口类型T或*T,返回值的Type字段和Func字段描述方法的未绑定函数状态
    // 对接口类型,返回值的Type字段描述方法的签名,Func字段为nil
    Method(int) Method
    // 根据方法名返回该类型方法集中的方法,使用一个布尔值说明是否发现该方法
    // 对非接口类型T或*T,返回值的Type字段和Func字段描述方法的未绑定函数状态
    // 对接口类型,返回值的Type字段描述方法的签名,Func字段为nil
    MethodByName(string) (Method, bool)
    // 内含隐藏或非导出方法
}

Type类型用来表示一个go类型。

不是所有go类型的Type值都能使用所有方法。请参见每个方法的文档获取使用限制。在调用有分类限定的方法时,应先使用Kind方法获知类型的分类。调用该分类不支持的方法会导致运行时的panic。

func TypeOf

func TypeOf(i interface{}) Type

TypeOf返回接口中保存的值的类型,TypeOf(nil)会返回nil。

func PtrTo

func PtrTo(t Type) Type

PtrTo返回类型t的指针的类型。

func SliceOf

func SliceOf(t Type) Type

SliceOf返回类型t的切片的类型。

func MapOf

func MapOf(key, elem Type) Type

MapOf返回一个键类型为key,值类型为elem的映射类型。如果key代表的类型不是合法的映射键类型(即它未实现go的==操作符),本函数会panic。

func ChanOf

func ChanOf(dir ChanDir, t Type) Type

ChanOf返回元素类型为t、方向为dir的通道类型。运行时GC强制将通道的元素类型的大小限定为64kb。如果t的尺寸大于或等于该限制,本函数将会panic。

type Value

type Value struct {
    // typ holds the type of the value represented by a Value.
    typ *rtype

    // Pointer-valued data or, if flagIndir is set, pointer to data.
    // Valid when either flagIndir is set or typ.pointers() is true.
    ptr unsafe.Pointer

    // flag holds metadata about the value.
    // The lowest bits are flag bits:
    //  - flagStickyRO: obtained via unexported not embedded field, so read-only
    //  - flagEmbedRO: obtained via unexported embedded field, so read-only
    //  - flagIndir: val holds a pointer to the data
    //  - flagAddr: v.CanAddr is true (implies flagIndir)
    //  - flagMethod: v is a method value.
    // The next five bits give the Kind of the value.
    // This repeats typ.Kind() except for method values.
    // The remaining 23+ bits give a method number for method values.
    // If flag.kind() != Func, code can assume that flagMethod is unset.
    // If ifaceIndir(typ), code can assume that flagIndir is set.
    flag

    // A method value represents a curried method invocation
    // like r.Read for some receiver r. The typ+val+flag bits describe
    // the receiver r, but the flag's Kind bits say Func (methods are
    // functions), and the top bits of the flag give the method number
    // in r's type's method table.
}

Value为go值提供了反射接口。

不是所有go类型值的Value表示都能使用所有方法。请参见每个方法的文档获取使用限制。在调用有分类限定的方法时,应先使用Kind方法获知该值的分类。调用该分类不支持的方法会导致运行时的panic。

Value类型的零值表示不持有某个值。零值的IsValid方法返回false,其Kind方法返回Invalid,而String方法返回"<invalid Value>",所有其它方法都会panic。绝大多数函数和方法都永远不返回Value零值。如果某个函数/方法返回了非法的Value,它的文档必须显式的说明具体情况。

如果某个go类型值可以安全的用于多线程并发操作,它的Value表示也可以安全的用于并发。

func ValueOf

func ValueOf(i interface{}) Value

ValueOf返回一个初始化为i接口保管的具体值的Value,ValueOf(nil)返回Value零值。

func Zero

func Zero(typ Type) Value

Zero返回一个持有类型typ的零值的Value。注意持有零值的Value和Value零值是两回事。Value零值表示不持有任何值。例如Zero(TypeOf(42))返回一个Kind为Int、值为0的Value。Zero的返回值不能设置也不会寻址。

func New

func New(typ Type) Value

New返回一个Value类型值,该值持有一个指向类型为typ的新申请的零值的指针,返回值的Type为PtrTo(typ)。

func NewAt

func NewAt(typ Type, p unsafe.Pointer) Value

NewAt返回一个Value类型值,该值持有一个指向类型为typ、地址为p的值的指针。

func Indirect

func Indirect(v Value) Value

返回持有v持有的指针指向的值的Value。如果v持有nil指针,会返回Value零值;如果v不持有指针,会返回v。

func MakeSlice

func MakeSlice(typ Type, len, cap int) Value

MakeSlice创建一个新申请的元素类型为typ,长度len容量cap的切片类型的Value值。

func MakeMap

func MakeMap(typ Type) Value

MakeMap创建一个特定映射类型的Value值。

func MakeChan

func MakeChan(typ Type, buffer int) Value

MakeChan创建一个元素类型为typ、有buffer个缓存的通道类型的Value值。

func MakeFunc

func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value

MakeFunc返回一个具有给定类型、包装函数fn的函数的Value封装。当被调用时,该函数会:

- 将提供给它的参数转化为Value切片
- 执行results := fn(args)
- 将results中每一个result依次排列作为返回值

函数fn的实现可以假设参数Value切片匹配typ类型指定的参数数目和类型。如果typ表示一个可变参数函数类型,参数切片中最后一个Value本身必须是一个包含所有可变参数的切片。fn返回的结果Value切片也必须匹配typ类型指定的结果数目和类型。

Value.Call方法允许程序员使用Value调用一个有类型约束的函数;反过来,MakeFunc方法允许程序员使用Value实现一个有类型约束的函数。

下例是一个用MakeFunc创建一个生成不同参数类型的swap函数的代码及其说明。

swap := func(in []reflect.Value) []reflect.Value {
    return []reflect.Value{in[1], in[0]}
}

makeSwap := func(fptr interface{}) {
    fn := reflect.ValueOf(fptr).Elem()
    // Make a function of the right type.
    v := reflect.MakeFunc(fn.Type(), swap)
    // Assign it to the value fn represents.
    fn.Set(v)
}
// Make and call a swap function for ints.
var intSwap func(int, int) (int, int)
makeSwap(&intSwap)
fmt.Println(intSwap(0, 1))
// Make and call a swap function for float64s.
var floatSwap func(float64, float64) (float64, float64)
makeSwap(&floatSwap)
fmt.Println(floatSwap(2.72, 3.14))

// 1 0
// 3.14 2.72

func Append

func Append(s Value, x ...Value) Value

向切片类型的Value值s中添加一系列值,x等Value值持有的值必须能直接赋值给s持有的切片的元素类型。

func AppendSlice

func AppendSlice(s, t Value) Value

类似Append函数,但接受一个切片类型的Value值。将切片t的每一个值添加到s。

func (Value) IsValid

func (v Value) IsValid() bool

IsValid返回v是否持有一个值。如果v是Value零值会返回假,此时v除了IsValid、String、Kind之外的方法都会导致panic。绝大多数函数和方法都永远不返回Value零值。如果某个函数/方法返回了非法的Value,它的文档必须显式的说明具体情况。

func (Value) IsNil

func (v Value) IsNil() bool

IsNil报告v持有的值是否为nil。v持有的值的分类必须是通道、函数、接口、映射、指针、切片之一;否则IsNil函数会导致panic。注意IsNil并不总是等价于go语言中值与nil的常规比较。例如:如果v是通过使用某个值为nil的接口调用ValueOf函数创建的,v.IsNil()返回真,但是如果v是Value零值,会panic。

func (Value) Kind

func (v Value) Kind() Kind

Kind返回v持有的值的分类,如果v是Value零值,返回值为Invalid

func (Value) Type

func (v Value) Type() Type

返回v持有的值的类型的Type表示。

func (Value) Convert

func (v Value) Convert(t Type) Value

Convert将v持有的值转换为类型为t的值,并返回该值的Value封装。如果go转换规则不支持这种转换,会panic。

func (Value) Elem

func (v Value) Elem() Value

Elem返回v持有的接口保管的值的Value封装,或者v持有的指针指向的值的Value封装。如果v的Kind不是Interface或Ptr会panic;如果v持有的值为nil,会返回Value零值。

func (Value) Bool

func (v Value) Bool() bool

返回v持有的布尔值,如果v的Kind不是Bool会panic

func (Value) Int

func (v Value) Int() int64

返回v持有的有符号整数(表示为int64),如果v的Kind不是Int、Int8、Int16、Int32、Int64会panic

func (Value) OverflowInt

func (v Value) OverflowInt(x int64) bool

如果v持有值的类型不能无溢出的表示x,会返回真。如果v的Kind不是Int、Int8、Int16、Int32、Int64会panic

func (Value) Uint

func (v Value) Uint() uint64

返回v持有的无符号整数(表示为uint64),如v的Kind不是Uint、Uintptr、Uint8、Uint16、Uint32、Uint64会panic

func (Value) OverflowUint

func (v Value) OverflowUint(x uint64) bool

如果v持有值的类型不能无溢出的表示x,会返回真。如果v的Kind不是Uint、Uintptr、Uint8、Uint16、Uint32、Uint64会panic

func (Value) Float

func (v Value) Float() float64

返回v持有的浮点数(表示为float64),如果v的Kind不是Float32、Float64会panic

func (Value) OverflowFloat

func (v Value) OverflowFloat(x float64) bool

如果v持有值的类型不能无溢出的表示x,会返回真。如果v的Kind不是Float32、Float64会panic

func (Value) Complex

func (v Value) Complex() complex128

返回v持有的复数(表示为complex64),如果v的Kind不是Complex64、Complex128会panic

func (Value) OverflowComplex

func (v Value) OverflowComplex(x complex128) bool

如果v持有值的类型不能无溢出的表示x,会返回真。如果v的Kind不是Complex64、Complex128会panic

func (Value) Pointer

func (v Value) Pointer() uintptr

将v持有的值作为一个指针返回。本方法返回值不是unsafe.Pointer类型,以避免程序员不显式导入unsafe包却得到unsafe.Pointer类型表示的指针。如果v的Kind不是Chan、Func、Map、Ptr、Slice或UnsafePointer会panic。

如果v的Kind是Func,返回值是底层代码的指针,但并不足以用于区分不同的函数;只能保证当且仅当v持有函数类型零值nil时,返回值为0。

如果v的Kind是Slice,返回值是指向切片第一个元素的指针。如果持有的切片为nil,返回值为0;如果持有的切片没有元素但不是nil,返回值不会是0。

func (Value) Bytes

func (v Value) Bytes() []byte

返回v持有的[]byte类型值。如果v持有的值的类型不是[]byte会panic。

func (Value) String

func (v Value) String() string

返回v持有的值的字符串表示。因为go的String方法的惯例,Value的String方法比较特别。和其他获取v持有值的方法不同:v的Kind是String时,返回该字符串;v的Kind不是String时也不会panic而是返回格式为"<T value>"的字符串,其中T是v持有值的类型。

func (Value) InterfaceData

func (v Value) InterfaceData() [2]uintptr

返回v持有的接口类型值的数据。如果v的Kind不是Interface会panic

func (Value) Slice

func (v Value) Slice(i, j int) Value

返回v[i:j](v持有的切片的子切片的Value封装);如果v的Kind不是Array、Slice或String会panic。如果v是一个不可寻址的数组,或者索引出界,也会panic

func (Value) Slice3

func (v Value) Slice3(i, j, k int) Value

是Slice的3参数版本,返回v[i:j:k] ;如果v的Kind不是Array、Slice或String会panic。如果v是一个不可寻址的数组,或者索引出界,也会panic。

func (Value) Cap

func (v Value) Cap() int

返回v持有值的容量,如果v的Kind不是Array、Chan、Slice会panic

func (Value) Len

func (v Value) Len() int

返回v持有值的长度,如果v的Kind不是Array、Chan、Slice、Map、String会panic

func (Value) Index

func (v Value) Index(i int) Value

返回v持有值的第i个元素。如果v的Kind不是Array、Chan、Slice、String,或者i出界,会panic

func (Value) MapIndex

func (v Value) MapIndex(key Value) Value

返回v持有值里key持有值为键对应的值的Value封装。如果v的Kind不是Map会panic。如果未找到对应值或者v持有值是nil映射,会返回Value零值。key的持有值必须可以直接赋值给v持有值类型的键类型。

func (Value) MapKeys

func (v Value) MapKeys() []Value

返回一个包含v持有值中所有键的Value封装的切片,该切片未排序。如果v的Kind不是Map会panic。如果v持有值是nil,返回空切片(非nil)。

func (Value) NumField

func (v Value) NumField() int

返回v持有的结构体类型值的字段数,如果v的Kind不是Struct会panic

func (Value) Field

func (v Value) Field(i int) Value

返回结构体的第i个字段(的Value封装)。如果v的Kind不是Struct或i出界会panic

func (Value) FieldByIndex

func (v Value) FieldByIndex(index []int) Value

返回索引序列指定的嵌套字段的Value表示,等价于用索引中的值链式调用本方法,如v的Kind非Struct将会panic

func (Value) FieldByName

func (v Value) FieldByName(name string) Value

返回该类型名为name的字段(的Value封装)(会查找匿名字段及其子字段),如果v的Kind不是Struct会panic;如果未找到会返回Value零值。

func (Value) FieldByNameFunc

返回该类型第一个字段名满足match的字段(的Value封装)(会查找匿名字段及其子字段),如果v的Kind不是Struct会panic;如果未找到会返回Value零值。

func (Value) Recv

func (v Value) Recv() (x Value, ok bool)

方法从v持有的通道接收并返回一个值(的Value封装)。如果v的Kind不是Chan会panic。方法会阻塞直到获取到值。如果返回值x对应于某个发送到v持有的通道的值,ok为真;如果因为通道关闭而返回,x为Value零值而ok为假。

func (Value) TryRecv

func (v Value) TryRecv() (x Value, ok bool)

TryRecv尝试从v持有的通道接收一个值,但不会阻塞。如果v的Kind不是Chan会panic。如果方法成功接收到一个值,会返回该值(的Value封装)和true;如果不能无阻塞的接收到值,返回Value零值和false;如果因为通道关闭而返回,返回值x是持有通道元素类型的零值的Value和false。

func (Value) Send

func (v Value) Send(x Value)

方法向v持有的通道发送x持有的值。如果v的Kind不是Chan,或者x的持有值不能直接赋值给v持有通道的元素类型,会panic。

func (Value) TrySend

func (v Value) TrySend(x Value) bool

TrySend尝试向v持有的通道发送x持有的值,但不会阻塞。如果v的Kind不是Chan会panic。如果成功发送会返回真,否则返回假。x的持有值必须可以直接赋值给v持有通道的元素类型。

func (Value) Close

func (v Value) Close()

关闭v持有的通道,如果v的Kind不是Chan会panic

func (Value) Call

func (v Value) Call(in []Value) []Value

Call方法使用输入的参数in调用v持有的函数。例如,如果len(in) == 3,v.Call(in)代表调用v(in[0], in[1], in[2])(其中Value值表示其持有值)。如果v的Kind不是Func会panic。它返回函数所有输出结果的Value封装的切片。和go代码一样,每一个输入实参的持有值都必须可以直接赋值给函数对应输入参数的类型。如果v持有值是可变参数函数,Call方法会自行创建一个代表可变参数的切片,将对应可变参数的值都拷贝到里面。

func (Value) CallSlice

func (v Value) CallSlice(in []Value) []Value

CallSlice调用v持有的可变参数函数,会将切片类型的in[len(in)-1](的成员)分配给v的最后的可变参数。例如,如果len(in) == 3,v.Call(in)代表调用v(in[0], in[1], in[2])(其中Value值表示其持有值,可变参数函数的可变参数位置提供一个切片并跟三个点号代表"解切片")。如果v的Kind不是Func或者v的持有值不是可变参数函数,会panic。它返回函数所有输出结果的Value封装的切片。和go代码一样,每一个输入实参的持有值都必须可以直接赋值给函数对应输入参数的类型。

func (Value) NumMethod

func (v Value) NumMethod() int

返回v持有值的方法集的方法数目。

func (Value) Method

func (v Value) Method(i int) Value

返回v持有值类型的第i个方法的已绑定(到v的持有值的)状态的函数形式的Value封装。返回值调用Call方法时不应包含接收者;返回值持有的函数总是使用v的持有者作为接收者(即第一个参数)。如果i出界,或者v的持有值是接口类型的零值(nil),会panic。

func (Value) MethodByName

func (v Value) MethodByName(name string) Value

返回v的名为name的方法的已绑定(到v的持有值的)状态的函数形式的Value封装。返回值调用Call方法时不应包含接收者;返回值持有的函数总是使用v的持有者作为接收者(即第一个参数)。如果未找到该方法,会返回一个Value零值。

func (Value) CanAddr

func (v Value) CanAddr() bool

返回是否可以获取v持有值的指针。可以获取指针的值被称为可寻址的。如果一个值是切片或可寻址数组的元素、可寻址结构体的字段、或从指针解引用得到的,该值即为可寻址的。

func (Value) Addr

func (v Value) Addr() Value

函数返回一个持有指向v持有者的指针的Value封装。如果v.CanAddr()返回假,调用本方法会panic。Addr一般用于获取结构体字段的指针或者切片的元素(的Value封装)以便调用需要指针类型接收者的方法。

func (Value) UnsafeAddr

func (v Value) UnsafeAddr() uintptr

返回指向v持有数据的地址的指针(表示为uintptr)以用作高级用途,如果v不可寻址会panic。

func (Value) CanInterface

func (v Value) CanInterface() bool

如果CanInterface返回真,v可以不导致panic的调用Interface方法。

func (Value) Interface

func (v Value) Interface() (i interface{})

本方法返回v当前持有的值(表示为/保管在interface{}类型),等价于:

var i interface{} = (v's underlying value)

如果v是通过访问非导出结构体字段获取的,会导致panic。

func (Value) CanSet

func (v Value) CanSet() bool

如果v持有的值可以被修改,CanSet就会返回真。只有一个Value持有值可以被寻址同时又不是来自非导出字段时,它才可以被修改。如果CanSet返回假,调用Set或任何限定类型的设置函数(如SetBool、SetInt64)都会panic。

func (Value) SetBool

func (v Value) SetBool(x bool)

设置v的持有值。如果v的Kind不是Bool或者v.CanSet()返回假,会panic。

func (Value) SetInt

func (v Value) SetInt(x int64)

设置v的持有值。如果v的Kind不是Int、Int8、Int16、Int32、Int64之一或者v.CanSet()返回假,会panic。

func (Value) SetUint

func (v Value) SetUint(x uint64)

设置v的持有值。如果v的Kind不是Uint、Uintptr、Uint8、Uint16、Uint32、Uint64或者v.CanSet()返回假,会panic。

func (Value) SetFloat

func (v Value) SetFloat(x float64)

设置v的持有值。如果v的Kind不是Float32、Float64或者v.CanSet()返回假,会panic。

func (Value) SetComplex

func (v Value) SetComplex(x complex128)

设置v的持有值。如果v的Kind不是Complex64、Complex128或者v.CanSet()返回假,会panic。

func (Value) SetBytes

func (v Value) SetBytes(x []byte)

设置v的持有值。如果v持有值不是[]byte类型或者v.CanSet()返回假,会panic。

func (Value) SetString

func (v Value) SetString(x string)

设置v的持有值。如果v的Kind不是String或者v.CanSet()返回假,会panic。

func (Value) SetPointer

func (v Value) SetPointer(x unsafe.Pointer)

设置v的持有值。如果v的Kind不是UnsafePointer或者v.CanSet()返回假,会panic。

func (Value) SetCap

func (v Value) SetCap(n int)

设定v持有值的容量。如果v的Kind不是Slice或者n出界(小于长度或超出容量),将导致panic

func (Value) SetLen

func (v Value) SetLen(n int)

设定v持有值的长度。如果v的Kind不是Slice或者n出界(小于零或超出容量),将导致panic

func (Value) SetMapIndex

func (v Value) SetMapIndex(key, val Value)

用来给v的映射类型持有值添加/修改键值对,如果val是Value零值,则是删除键值对。如果v的Kind不是Map,或者v的持有值是nil,将会panic。key的持有值必须可以直接赋值给v持有值类型的键类型。val的持有值必须可以直接赋值给v持有值类型的值类型。

func (Value) Set

func (v Value) Set(x Value)

将v的持有值修改为x的持有值。如果v.CanSet()返回假,会panic。x的持有值必须能直接赋给v持有值的类型。

func Copy

func Copy(dst, src Value) int

将src中的值拷贝到dst,直到src被耗尽或者dst被装满,要求这二者都是slice或array,且元素类型相同。

func DeepEqual

func DeepEqual(a1, a2 interface{}) bool

用来判断两个值是否深度一致:除了类型相同;在可以时(主要是基本类型)会使用==;但还会比较array、slice的成员,map的键值对,结构体字段进行深入比对。map的键值对,对键只使用==,但值会继续往深层比对。DeepEqual函数可以正确处理循环的类型。函数类型只有都会nil时才相等;空切片不等于nil切片;还会考虑array、slice的长度、map键值对数。

Bugs

FieldByName及相关的函数会将名称相同的结构体字段视为相同的字段,即使它们是来自不同包的非导出字段。这导致如果结构体类型t包含多个名为x的字段的话(被不同的包嵌入)t.FieldByName("x")的行为没有良好的定义。FieldByName可能会返回其中一个名为x的字段,也可能报告说没有这个字段。细节参见golang.org/issue/4876。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:DevilRoshan

查看原文:Golang标准库——reflect

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

523 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传