// Type is the representation of a Go type. // 并非所有方法都适用于所有类型。在每种方法的文档中都注明了限制(如有) // Not all methods apply to all kinds of types. Restrictions, // if any, are noted in the documentation for each method. // 在调用特定于种类的方法之前,请使用Kind方法找出类型。调用不适合该类型的方法会导致运行时panic。 // Use the Kind method to find out the kind of type before // calling kind-specific methods. Calling a method // inappropriate to the kind of type causes a run-time panic. // // Type values are comparable, such as with the == operator, // so they can be used as map keys. // Two Type values are equal if they represent identical types. type Type interface { // Methods applicable to all types.
// Align returns the alignment in bytes of a value of // this type when allocated in memory. //内存对齐字节数 Align() int
// FieldAlign returns the alignment in bytes of a value of // this type when used as a field in a struct. //结构体中对齐字节数 FieldAlign() int
// Method returns the i'th method in the type's method set. // It panics if i is not in the range [0, NumMethod()). //非接口类型,返回带接受者的方法 // For a non-interface type T or *T, the returned Method's Type and Func // fields describe a function whose first argument is the receiver. //接口类型,返回函数签名,不带接收者 // For an interface type, the returned Method's Type field gives the // method signature, without a receiver, and the Func field is nil. // // Only exported methods are accessible and they are sorted in // lexicographic order.
//返回第i个method Method(int) Method
// MethodByName returns the method with that name in the type's // method set and a boolean indicating if the method was found. // // For a non-interface type T or *T, the returned Method's Type and Func // fields describe a function whose first argument is the receiver. // // For an interface type, the returned Method's Type field gives the // method signature, without a receiver, and the Func field is nil. //返回对应名字的method MethodByName(string) (Method, bool)
// NumMethod returns the number of exported methods in the type's method set. //返回method的总数 NumMethod() int
// Name returns the type's name within its package for a defined type. // For other (non-defined) types it returns the empty string. //返回类型名 Name() string
// PkgPath returns a defined type's package path, that is, the import path // that uniquely identifies the package, such as "encoding/base64". // If the type was predeclared (string, error) or not defined (*T, struct{}, // []int, or A where A is an alias for a non-defined type), the package path // will be the empty string. PkgPath() string
// Size returns the number of bytes needed to store // a value of the given type; it is analogous to unsafe.Sizeof. Size() uintptr
// String returns a string representation of the type. // The string representation may use shortened package names // (e.g., base64 instead of "encoding/base64") and is not // guaranteed to be unique among types. To test for type identity, // compare the Types directly. //返回字符串的类型描述,比较类型的话直接用Type别用这个 String() string
// Kind returns the specific kind of this type. //返回特定的类型 Kind() Kind
// Implements reports whether the type implements the interface type u. Implements(u Type) bool
// AssignableTo reports whether a value of the type is assignable to type u. // AssignableTo(u Type) bool
// ConvertibleTo reports whether a value of the type is convertible to type u. ConvertibleTo(u Type) bool
// Comparable reports whether values of this type are comparable. Comparable() bool
// Methods applicable only to some types, depending on Kind. // The methods allowed for each kind are: // // Int*, Uint*, Float*, Complex*: Bits // Array: Elem, Len // Chan: ChanDir, Elem // Func: In, NumIn, Out, NumOut, IsVariadic. // Map: Key, Elem // Ptr: Elem // Slice: Elem // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
// Bits returns the size of the type in bits. // It panics if the type's Kind is not one of the // sized or unsized Int, Uint, Float, or Complex kinds. Bits() int
// ChanDir returns a channel type's direction. // It panics if the type's Kind is not Chan. ChanDir() ChanDir
// IsVariadic reports whether a function type's final input parameter // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's // implicit actual type []T. // // For concreteness, if t represents func(x int, y ... float64), then // // t.NumIn() == 2 // t.In(0) is the reflect.Type for "int" // t.In(1) is the reflect.Type for "[]float64" // t.IsVariadic() == true // // IsVariadic panics if the type's Kind is not Func. IsVariadic() bool
// Elem returns a type's element type. // It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice. //返回元素类型 Elem() Type
// Field returns a struct type's i'th field. // It panics if the type's Kind is not Struct. // It panics if i is not in the range [0, NumField()). //返回第i个字段 Field(i int) StructField
// FieldByIndex returns the nested field corresponding // to the index sequence. It is equivalent to calling Field // successively for each index i. // It panics if the type's Kind is not Struct. FieldByIndex(index []int) StructField
// FieldByName returns the struct field with the given name // and a boolean indicating if the field was found. //返回对应名称的字段 FieldByName(name string) (StructField, bool)
// FieldByNameFunc returns the struct field with a name // that satisfies the match function and a boolean indicating if // the field was found. // // FieldByNameFunc considers the fields in the struct itself // and then the fields in any embedded structs, in breadth first order, // stopping at the shallowest nesting depth containing one or more // fields satisfying the match function. If multiple fields at that depth // satisfy the match function, they cancel each other // and FieldByNameFunc returns no match. // This behavior mirrors Go's handling of name lookup in // structs containing embedded fields. FieldByNameFunc(match func(string)bool) (StructField, bool)
// In returns the type of a function type's i'th input parameter. // It panics if the type's Kind is not Func. // It panics if i is not in the range [0, NumIn()). //第i个入参 In(i int) Type
// Key returns a map type's key type. // It panics if the type's Kind is not Map. Key() Type
// Len returns an array type's length. // It panics if the type's Kind is not Array. Len() int
// NumField returns a struct type's field count. // It panics if the type's Kind is not Struct.
//字段数量 NumField() int
// NumIn returns a function type's input parameter count. // It panics if the type's Kind is not Func. //函数入参个数 NumIn() int
// NumOut returns a function type's output parameter count. // It panics if the type's Kind is not Func. //函数出参个数 NumOut() int
// Out returns the type of a function type's i'th output parameter. // It panics if the type's Kind is not Func. // It panics if i is not in the range [0, NumOut()). //第i个出参 Out(i int) Type
common() *rtype uncommon() *uncommonType }
简单测试下常用的函数:
Name
Name() string, Name returns the type’s name within its package for a defined type.For other (non-defined) types it returns the empty string.
/* * These data structures are known to the compiler (../../cmd/internal/gc/reflect.go). * A few are known to ../runtime/type.go to convey to debuggers. * They are also known to ../runtime/type.go. */
// A Kind represents the specific kind of type that a Type represents. // The zero Kind is not a valid kind. type Kind uint
// Main function funcmain() { //函数 t := reflect.TypeOf(func1) for i := 0; i < t.NumIn(); i++ { fmt.Println(t.In(i)) } fmt.Println("-------------")
for i := 0; i < t.NumOut(); i++ { fmt.Println(t.Out(i)) } fmt.Println("-------------")
//方法 typ := reflect.TypeOf(new(HHello)) fmt.Println(typ.NumMethod()) m := typ.Method(0) mt := m.Type fmt.Println(mt.NumIn()) for i := 0; i < mt.NumIn(); i++ { fmt.Println(mt.In(i)) } }
output:
1 2 3 4 5 6 7 8 9 10 11
int string ------------- int int ------------- 1 3 *main.HHello string *string
// Value is the reflection interface to a Go value. // // Not all methods apply to all kinds of values. Restrictions, // if any, are noted in the documentation for each method. // Use the Kind method to find out the kind of value before // calling kind-specific methods. Calling a method // inappropriate to the kind of type causes a run time panic. // // The zero Value represents no value. // Its IsValid method returns false, its Kind method returns Invalid, // its String method returns "<invalid Value>", and all other methods panic. // Most functions and methods never return an invalid value. // If one does, its documentation states the conditions explicitly. // // A Value can be used concurrently by multiple goroutines provided that // the underlying Go value can be used concurrently for the equivalent // direct operations. // // To compare two Values, compare the results of the Interface method. // Using == on two Values does not compare the underlying values // they represent. 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. }
// Elem returns the value that the interface v contains // or that the pointer v points to. // It panics if v's Kind is not Interface or Ptr. // It returns the zero Value if v is nil.
package main
import ( "fmt" "reflect" )
type User struct { Id int Name string Age int }
// Main function funcmain() { //v := reflect.ValueOf(User{Id: 1, Name: "river", Age: 26}) //fmt.Println(v.Elem()) //panic
v := reflect.ValueOf(&User{Id: 1, Name: "river", Age: 26}) fmt.Println(v.Elem()) //{1 river 26}
// var vv reflect.Value // fmt.Println(vv.Elem()) //panic
v = reflect.ValueOf(&User{}) fmt.Println(v.Elem()) //{0 0} }
// Main function funcmain() { v := reflect.ValueOf(User{Id: 1, Name: "river", Age: 26}) fmt.Println(v.Kind()) //struct
v = reflect.ValueOf(1) fmt.Println(v.Kind()) //int
v = reflect.ValueOf("2222") fmt.Println(v.Kind()) //string
v = reflect.ValueOf([]int{1, 2, 3}) fmt.Println(v.Kind()) //slice
v = reflect.ValueOf(ff) fmt.Println(v.Kind()) //func }
感觉和Type的Kind没啥区别
Set Addr
CanAddr reports whether the value’s address can be obtained with Addr. Such values are called addressable. A value is addressable if it is an element of a slice, an element of an addressable array, a field of an addressable struct, or the result of dereferencing a pointer. If CanAddr returns false, calling Addr will panic.
If a reflect.Value is a pointer, then v.Elem() is equivalent to reflect.Indirect(v). If it is not a pointer, then they are not equivalent:
If the value is an interface then reflect.Indirect(v) will return the same value, while v.Elem() will return the contained dynamic value.
If the value is something else, then v.Elem() will panic.
The reflect.Indirect helper is intended for cases where you want to accept either a particular type, or a pointer to that type. One example is the database/sql conversion routines: by using reflect.Indirect, it can use the same code paths to handle the various types and pointers to those types.