The Go Programming Language

Source file src/pkg/reflect/type.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package reflect implements run-time reflection, allowing a program to
     6	// manipulate objects with arbitrary types.  The typical use is to take a value
     7	// with static type interface{} and extract its dynamic type information by
     8	// calling TypeOf, which returns a Type.
     9	//
    10	// A call to ValueOf returns a Value representing the run-time data.
    11	// Zero takes a Type and returns a Value representing a zero value
    12	// for that type.
    13	//
    14	// See "The Laws of Reflection" for an introduction to reflection in Go:
    15	// http://blog.golang.org/2011/09/laws-of-reflection.html
    16	package reflect
    17	
    18	import (
    19		"runtime"
    20		"strconv"
    21		"sync"
    22		"unsafe"
    23	)
    24	
    25	// Type is the representation of a Go type.
    26	//
    27	// Not all methods apply to all kinds of types.  Restrictions,
    28	// if any, are noted in the documentation for each method.
    29	// Use the Kind method to find out the kind of type before
    30	// calling kind-specific methods.  Calling a method
    31	// inappropriate to the kind of type causes a run-time panic.
    32	type Type interface {
    33		// Methods applicable to all types.
    34	
    35		// Align returns the alignment in bytes of a value of
    36		// this type when allocated in memory.
    37		Align() int
    38	
    39		// FieldAlign returns the alignment in bytes of a value of
    40		// this type when used as a field in a struct.
    41		FieldAlign() int
    42	
    43		// Method returns the i'th method in the type's method set.
    44		// It panics if i is not in the range [0, NumMethod()).
    45		//
    46		// For a non-interface type T or *T, the returned Method's Type and Func
    47		// fields describe a function whose first argument is the receiver.
    48		//
    49		// For an interface type, the returned Method's Type field gives the
    50		// method signature, without a receiver, and the Func field is nil.
    51		Method(int) Method
    52	
    53		// MethodByName returns the method with that name in the type's
    54		// method set and a boolean indicating if the method was found.
    55		//
    56		// For a non-interface type T or *T, the returned Method's Type and Func
    57		// fields describe a function whose first argument is the receiver.
    58		//
    59		// For an interface type, the returned Method's Type field gives the
    60		// method signature, without a receiver, and the Func field is nil.
    61		MethodByName(string) (Method, bool)
    62	
    63		// NumMethod returns the number of methods in the type's method set.
    64		NumMethod() int
    65	
    66		// Name returns the type's name within its package.
    67		// It returns an empty string for unnamed types.
    68		Name() string
    69	
    70		// PkgPath returns the type's package path.
    71		// The package path is a full package import path like "container/vector".
    72		// PkgPath returns an empty string for unnamed types.
    73		PkgPath() string
    74	
    75		// Size returns the number of bytes needed to store
    76		// a value of the given type; it is analogous to unsafe.Sizeof.
    77		Size() uintptr
    78	
    79		// String returns a string representation of the type.
    80		// The string representation may use shortened package names
    81		// (e.g., vector instead of "container/vector") and is not
    82		// guaranteed to be unique among types.  To test for equality,
    83		// compare the Types directly.
    84		String() string
    85	
    86		// Kind returns the specific kind of this type.
    87		Kind() Kind
    88	
    89		// Implements returns true if the type implements the interface type u.
    90		Implements(u Type) bool
    91	
    92		// AssignableTo returns true if a value of the type is assignable to type u.
    93		AssignableTo(u Type) bool
    94	
    95		// Methods applicable only to some types, depending on Kind.
    96		// The methods allowed for each kind are:
    97		//
    98		//	Int*, Uint*, Float*, Complex*: Bits
    99		//	Array: Elem, Len
   100		//	Chan: ChanDir, Elem
   101		//	Func: In, NumIn, Out, NumOut, IsVariadic.
   102		//	Map: Key, Elem
   103		//	Ptr: Elem
   104		//	Slice: Elem
   105		//	Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
   106	
   107		// Bits returns the size of the type in bits.
   108		// It panics if the type's Kind is not one of the
   109		// sized or unsized Int, Uint, Float, or Complex kinds.
   110		Bits() int
   111	
   112		// ChanDir returns a channel type's direction.
   113		// It panics if the type's Kind is not Chan.
   114		ChanDir() ChanDir
   115	
   116		// IsVariadic returns true if a function type's final input parameter
   117		// is a "..." parameter.  If so, t.In(t.NumIn() - 1) returns the parameter's
   118		// implicit actual type []T.
   119		//
   120		// For concreteness, if t represents func(x int, y ... float64), then
   121		//
   122		//	t.NumIn() == 2
   123		//	t.In(0) is the reflect.Type for "int"
   124		//	t.In(1) is the reflect.Type for "[]float64"
   125		//	t.IsVariadic() == true
   126		//
   127		// IsVariadic panics if the type's Kind is not Func.
   128		IsVariadic() bool
   129	
   130		// Elem returns a type's element type.
   131		// It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
   132		Elem() Type
   133	
   134		// Field returns a struct type's i'th field.
   135		// It panics if the type's Kind is not Struct.
   136		// It panics if i is not in the range [0, NumField()).
   137		Field(i int) StructField
   138	
   139		// FieldByIndex returns the nested field corresponding
   140		// to the index sequence.  It is equivalent to calling Field
   141		// successively for each index i.
   142		// It panics if the type's Kind is not Struct.
   143		FieldByIndex(index []int) StructField
   144	
   145		// FieldByName returns the struct field with the given name
   146		// and a boolean indicating if the field was found.
   147		FieldByName(name string) (StructField, bool)
   148	
   149		// FieldByNameFunc returns the first struct field with a name
   150		// that satisfies the match function and a boolean indicating if
   151		// the field was found.
   152		FieldByNameFunc(match func(string) bool) (StructField, bool)
   153	
   154		// In returns the type of a function type's i'th input parameter.
   155		// It panics if the type's Kind is not Func.
   156		// It panics if i is not in the range [0, NumIn()).
   157		In(i int) Type
   158	
   159		// Key returns a map type's key type.
   160		// It panics if the type's Kind is not Map.
   161		Key() Type
   162	
   163		// Len returns an array type's length.
   164		// It panics if the type's Kind is not Array.
   165		Len() int
   166	
   167		// NumField returns a struct type's field count.
   168		// It panics if the type's Kind is not Struct.
   169		NumField() int
   170	
   171		// NumIn returns a function type's input parameter count.
   172		// It panics if the type's Kind is not Func.
   173		NumIn() int
   174	
   175		// NumOut returns a function type's output parameter count.
   176		// It panics if the type's Kind is not Func.
   177		NumOut() int
   178	
   179		// Out returns the type of a function type's i'th output parameter.
   180		// It panics if the type's Kind is not Func.
   181		// It panics if i is not in the range [0, NumOut()).
   182		Out(i int) Type
   183	
   184		runtimeType() *runtime.Type
   185		common() *commonType
   186		uncommon() *uncommonType
   187	}
   188	
   189	// A Kind represents the specific kind of type that a Type represents.
   190	// The zero Kind is not a valid kind.
   191	type Kind uint8
   192	
   193	const (
   194		Invalid Kind = iota
   195		Bool
   196		Int
   197		Int8
   198		Int16
   199		Int32
   200		Int64
   201		Uint
   202		Uint8
   203		Uint16
   204		Uint32
   205		Uint64
   206		Uintptr
   207		Float32
   208		Float64
   209		Complex64
   210		Complex128
   211		Array
   212		Chan
   213		Func
   214		Interface
   215		Map
   216		Ptr
   217		Slice
   218		String
   219		Struct
   220		UnsafePointer
   221	)
   222	
   223	/*
   224	 * Copy of data structures from ../runtime/type.go.
   225	 * For comments, see the ones in that file.
   226	 *
   227	 * These data structures are known to the compiler and the runtime.
   228	 *
   229	 * Putting these types in runtime instead of reflect means that
   230	 * reflect doesn't need to be autolinked into every binary, which
   231	 * simplifies bootstrapping and package dependencies.
   232	 * Unfortunately, it also means that reflect needs its own
   233	 * copy in order to access the private fields.
   234	 */
   235	
   236	// commonType is the common implementation of most values.
   237	// It is embedded in other, public struct types, but always
   238	// with a unique tag like `reflect:"array"` or `reflect:"ptr"`
   239	// so that code cannot convert from, say, *arrayType to *ptrType.
   240	
   241	type commonType struct {
   242		size       uintptr
   243		hash       uint32
   244		alg        uint8
   245		align      uint8
   246		fieldAlign uint8
   247		kind       uint8
   248		string     *string
   249		*uncommonType
   250		ptrToThis *runtime.Type
   251	}
   252	
   253	type method struct {
   254		name    *string
   255		pkgPath *string
   256		mtyp    *runtime.Type
   257		typ     *runtime.Type
   258		ifn     unsafe.Pointer
   259		tfn     unsafe.Pointer
   260	}
   261	
   262	type uncommonType struct {
   263		name    *string
   264		pkgPath *string
   265		methods []method
   266	}
   267	
   268	// ChanDir represents a channel type's direction.
   269	type ChanDir int
   270	
   271	const (
   272		RecvDir ChanDir = 1 << iota
   273		SendDir
   274		BothDir = RecvDir | SendDir
   275	)
   276	
   277	// arrayType represents a fixed array type.
   278	type arrayType struct {
   279		commonType `reflect:"array"`
   280		elem       *runtime.Type
   281		slice      *runtime.Type
   282		len        uintptr
   283	}
   284	
   285	// chanType represents a channel type.
   286	type chanType struct {
   287		commonType `reflect:"chan"`
   288		elem       *runtime.Type
   289		dir        uintptr
   290	}
   291	
   292	// funcType represents a function type.
   293	type funcType struct {
   294		commonType `reflect:"func"`
   295		dotdotdot  bool
   296		in         []*runtime.Type
   297		out        []*runtime.Type
   298	}
   299	
   300	// imethod represents a method on an interface type
   301	type imethod struct {
   302		name    *string
   303		pkgPath *string
   304		typ     *runtime.Type
   305	}
   306	
   307	// interfaceType represents an interface type.
   308	type interfaceType struct {
   309		commonType `reflect:"interface"`
   310		methods    []imethod
   311	}
   312	
   313	// mapType represents a map type.
   314	type mapType struct {
   315		commonType `reflect:"map"`
   316		key        *runtime.Type
   317		elem       *runtime.Type
   318	}
   319	
   320	// ptrType represents a pointer type.
   321	type ptrType struct {
   322		commonType `reflect:"ptr"`
   323		elem       *runtime.Type
   324	}
   325	
   326	// sliceType represents a slice type.
   327	type sliceType struct {
   328		commonType `reflect:"slice"`
   329		elem       *runtime.Type
   330	}
   331	
   332	// Struct field
   333	type structField struct {
   334		name    *string
   335		pkgPath *string
   336		typ     *runtime.Type
   337		tag     *string
   338		offset  uintptr
   339	}
   340	
   341	// structType represents a struct type.
   342	type structType struct {
   343		commonType `reflect:"struct"`
   344		fields     []structField
   345	}
   346	
   347	/*
   348	 * The compiler knows the exact layout of all the data structures above.
   349	 * The compiler does not know about the data structures and methods below.
   350	 */
   351	
   352	// Method represents a single method.
   353	type Method struct {
   354		PkgPath string // empty for uppercase Name
   355		Name    string
   356		Type    Type
   357		Func    Value
   358		Index   int
   359	}
   360	
   361	// High bit says whether type has
   362	// embedded pointers,to help garbage collector.
   363	const kindMask = 0x7f
   364	
   365	func (k Kind) String() string {
   366		if int(k) < len(kindNames) {
   367			return kindNames[k]
   368		}
   369		return "kind" + strconv.Itoa(int(k))
   370	}
   371	
   372	var kindNames = []string{
   373		Invalid:       "invalid",
   374		Bool:          "bool",
   375		Int:           "int",
   376		Int8:          "int8",
   377		Int16:         "int16",
   378		Int32:         "int32",
   379		Int64:         "int64",
   380		Uint:          "uint",
   381		Uint8:         "uint8",
   382		Uint16:        "uint16",
   383		Uint32:        "uint32",
   384		Uint64:        "uint64",
   385		Uintptr:       "uintptr",
   386		Float32:       "float32",
   387		Float64:       "float64",
   388		Complex64:     "complex64",
   389		Complex128:    "complex128",
   390		Array:         "array",
   391		Chan:          "chan",
   392		Func:          "func",
   393		Interface:     "interface",
   394		Map:           "map",
   395		Ptr:           "ptr",
   396		Slice:         "slice",
   397		String:        "string",
   398		Struct:        "struct",
   399		UnsafePointer: "unsafe.Pointer",
   400	}
   401	
   402	func (t *uncommonType) uncommon() *uncommonType {
   403		return t
   404	}
   405	
   406	func (t *uncommonType) PkgPath() string {
   407		if t == nil || t.pkgPath == nil {
   408			return ""
   409		}
   410		return *t.pkgPath
   411	}
   412	
   413	func (t *uncommonType) Name() string {
   414		if t == nil || t.name == nil {
   415			return ""
   416		}
   417		return *t.name
   418	}
   419	
   420	func (t *commonType) toType() Type {
   421		if t == nil {
   422			return nil
   423		}
   424		return t
   425	}
   426	
   427	func (t *commonType) String() string { return *t.string }
   428	
   429	func (t *commonType) Size() uintptr { return t.size }
   430	
   431	func (t *commonType) Bits() int {
   432		if t == nil {
   433			panic("reflect: Bits of nil Type")
   434		}
   435		k := t.Kind()
   436		if k < Int || k > Complex128 {
   437			panic("reflect: Bits of non-arithmetic Type " + t.String())
   438		}
   439		return int(t.size) * 8
   440	}
   441	
   442	func (t *commonType) Align() int { return int(t.align) }
   443	
   444	func (t *commonType) FieldAlign() int { return int(t.fieldAlign) }
   445	
   446	func (t *commonType) Kind() Kind { return Kind(t.kind & kindMask) }
   447	
   448	func (t *commonType) common() *commonType { return t }
   449	
   450	func (t *uncommonType) Method(i int) (m Method) {
   451		if t == nil || i < 0 || i >= len(t.methods) {
   452			panic("reflect: Method index out of range")
   453		}
   454		p := &t.methods[i]
   455		if p.name != nil {
   456			m.Name = *p.name
   457		}
   458		flag := uint32(0)
   459		if p.pkgPath != nil {
   460			m.PkgPath = *p.pkgPath
   461			flag |= flagRO
   462		}
   463		m.Type = toType(p.typ)
   464		fn := p.tfn
   465		m.Func = valueFromIword(flag, m.Type, iword(fn))
   466		m.Index = i
   467		return
   468	}
   469	
   470	func (t *uncommonType) NumMethod() int {
   471		if t == nil {
   472			return 0
   473		}
   474		return len(t.methods)
   475	}
   476	
   477	func (t *uncommonType) MethodByName(name string) (m Method, ok bool) {
   478		if t == nil {
   479			return
   480		}
   481		var p *method
   482		for i := range t.methods {
   483			p = &t.methods[i]
   484			if p.name != nil && *p.name == name {
   485				return t.Method(i), true
   486			}
   487		}
   488		return
   489	}
   490	
   491	// TODO(rsc): 6g supplies these, but they are not
   492	// as efficient as they could be: they have commonType
   493	// as the receiver instead of *commonType.
   494	func (t *commonType) NumMethod() int {
   495		if t.Kind() == Interface {
   496			tt := (*interfaceType)(unsafe.Pointer(t))
   497			return tt.NumMethod()
   498		}
   499		return t.uncommonType.NumMethod()
   500	}
   501	
   502	func (t *commonType) Method(i int) (m Method) {
   503		if t.Kind() == Interface {
   504			tt := (*interfaceType)(unsafe.Pointer(t))
   505			return tt.Method(i)
   506		}
   507		return t.uncommonType.Method(i)
   508	}
   509	
   510	func (t *commonType) MethodByName(name string) (m Method, ok bool) {
   511		if t.Kind() == Interface {
   512			tt := (*interfaceType)(unsafe.Pointer(t))
   513			return tt.MethodByName(name)
   514		}
   515		return t.uncommonType.MethodByName(name)
   516	}
   517	
   518	func (t *commonType) PkgPath() string {
   519		return t.uncommonType.PkgPath()
   520	}
   521	
   522	func (t *commonType) Name() string {
   523		return t.uncommonType.Name()
   524	}
   525	
   526	func (t *commonType) ChanDir() ChanDir {
   527		if t.Kind() != Chan {
   528			panic("reflect: ChanDir of non-chan type")
   529		}
   530		tt := (*chanType)(unsafe.Pointer(t))
   531		return ChanDir(tt.dir)
   532	}
   533	
   534	func (t *commonType) IsVariadic() bool {
   535		if t.Kind() != Func {
   536			panic("reflect: IsVariadic of non-func type")
   537		}
   538		tt := (*funcType)(unsafe.Pointer(t))
   539		return tt.dotdotdot
   540	}
   541	
   542	func (t *commonType) Elem() Type {
   543		switch t.Kind() {
   544		case Array:
   545			tt := (*arrayType)(unsafe.Pointer(t))
   546			return toType(tt.elem)
   547		case Chan:
   548			tt := (*chanType)(unsafe.Pointer(t))
   549			return toType(tt.elem)
   550		case Map:
   551			tt := (*mapType)(unsafe.Pointer(t))
   552			return toType(tt.elem)
   553		case Ptr:
   554			tt := (*ptrType)(unsafe.Pointer(t))
   555			return toType(tt.elem)
   556		case Slice:
   557			tt := (*sliceType)(unsafe.Pointer(t))
   558			return toType(tt.elem)
   559		}
   560		panic("reflect; Elem of invalid type")
   561	}
   562	
   563	func (t *commonType) Field(i int) StructField {
   564		if t.Kind() != Struct {
   565			panic("reflect: Field of non-struct type")
   566		}
   567		tt := (*structType)(unsafe.Pointer(t))
   568		return tt.Field(i)
   569	}
   570	
   571	func (t *commonType) FieldByIndex(index []int) StructField {
   572		if t.Kind() != Struct {
   573			panic("reflect: FieldByIndex of non-struct type")
   574		}
   575		tt := (*structType)(unsafe.Pointer(t))
   576		return tt.FieldByIndex(index)
   577	}
   578	
   579	func (t *commonType) FieldByName(name string) (StructField, bool) {
   580		if t.Kind() != Struct {
   581			panic("reflect: FieldByName of non-struct type")
   582		}
   583		tt := (*structType)(unsafe.Pointer(t))
   584		return tt.FieldByName(name)
   585	}
   586	
   587	func (t *commonType) FieldByNameFunc(match func(string) bool) (StructField, bool) {
   588		if t.Kind() != Struct {
   589			panic("reflect: FieldByNameFunc of non-struct type")
   590		}
   591		tt := (*structType)(unsafe.Pointer(t))
   592		return tt.FieldByNameFunc(match)
   593	}
   594	
   595	func (t *commonType) In(i int) Type {
   596		if t.Kind() != Func {
   597			panic("reflect: In of non-func type")
   598		}
   599		tt := (*funcType)(unsafe.Pointer(t))
   600		return toType(tt.in[i])
   601	}
   602	
   603	func (t *commonType) Key() Type {
   604		if t.Kind() != Map {
   605			panic("reflect: Key of non-map type")
   606		}
   607		tt := (*mapType)(unsafe.Pointer(t))
   608		return toType(tt.key)
   609	}
   610	
   611	func (t *commonType) Len() int {
   612		if t.Kind() != Array {
   613			panic("reflect: Len of non-array type")
   614		}
   615		tt := (*arrayType)(unsafe.Pointer(t))
   616		return int(tt.len)
   617	}
   618	
   619	func (t *commonType) NumField() int {
   620		if t.Kind() != Struct {
   621			panic("reflect: NumField of non-struct type")
   622		}
   623		tt := (*structType)(unsafe.Pointer(t))
   624		return len(tt.fields)
   625	}
   626	
   627	func (t *commonType) NumIn() int {
   628		if t.Kind() != Func {
   629			panic("reflect; NumIn of non-func type")
   630		}
   631		tt := (*funcType)(unsafe.Pointer(t))
   632		return len(tt.in)
   633	}
   634	
   635	func (t *commonType) NumOut() int {
   636		if t.Kind() != Func {
   637			panic("reflect; NumOut of non-func type")
   638		}
   639		tt := (*funcType)(unsafe.Pointer(t))
   640		return len(tt.out)
   641	}
   642	
   643	func (t *commonType) Out(i int) Type {
   644		if t.Kind() != Func {
   645			panic("reflect: Out of non-func type")
   646		}
   647		tt := (*funcType)(unsafe.Pointer(t))
   648		return toType(tt.out[i])
   649	}
   650	
   651	func (d ChanDir) String() string {
   652		switch d {
   653		case SendDir:
   654			return "chan<-"
   655		case RecvDir:
   656			return "<-chan"
   657		case BothDir:
   658			return "chan"
   659		}
   660		return "ChanDir" + strconv.Itoa(int(d))
   661	}
   662	
   663	// Method returns the i'th method in the type's method set.
   664	func (t *interfaceType) Method(i int) (m Method) {
   665		if i < 0 || i >= len(t.methods) {
   666			return
   667		}
   668		p := &t.methods[i]
   669		m.Name = *p.name
   670		if p.pkgPath != nil {
   671			m.PkgPath = *p.pkgPath
   672		}
   673		m.Type = toType(p.typ)
   674		m.Index = i
   675		return
   676	}
   677	
   678	// NumMethod returns the number of interface methods in the type's method set.
   679	func (t *interfaceType) NumMethod() int { return len(t.methods) }
   680	
   681	// MethodByName method with the given name in the type's method set.
   682	func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
   683		if t == nil {
   684			return
   685		}
   686		var p *imethod
   687		for i := range t.methods {
   688			p = &t.methods[i]
   689			if *p.name == name {
   690				return t.Method(i), true
   691			}
   692		}
   693		return
   694	}
   695	
   696	type StructField struct {
   697		PkgPath   string // empty for uppercase Name
   698		Name      string
   699		Type      Type
   700		Tag       StructTag
   701		Offset    uintptr
   702		Index     []int
   703		Anonymous bool
   704	}
   705	
   706	// A StructTag is the tag string in a struct field.
   707	//
   708	// By convention, tag strings are a concatenation of
   709	// optionally space-separated key:"value" pairs.
   710	// Each key is a non-empty string consisting of non-control
   711	// characters other than space (U+0020 ' '), quote (U+0022 '"'),
   712	// and colon (U+003A ':').  Each value is quoted using U+0022 '"'
   713	// characters and Go string literal syntax.
   714	type StructTag string
   715	
   716	// Get returns the value associated with key in the tag string.
   717	// If there is no such key in the tag, Get returns the empty string.
   718	// If the tag does not have the conventional format, the value
   719	// returned by Get is unspecified, 
   720	func (tag StructTag) Get(key string) string {
   721		for tag != "" {
   722			// skip leading space
   723			i := 0
   724			for i < len(tag) && tag[i] == ' ' {
   725				i++
   726			}
   727			tag = tag[i:]
   728			if tag == "" {
   729				break
   730			}
   731	
   732			// scan to colon.
   733			// a space or a quote is a syntax error
   734			i = 0
   735			for i < len(tag) && tag[i] != ' ' && tag[i] != ':' && tag[i] != '"' {
   736				i++
   737			}
   738			if i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
   739				break
   740			}
   741			name := string(tag[:i])
   742			tag = tag[i+1:]
   743	
   744			// scan quoted string to find value
   745			i = 1
   746			for i < len(tag) && tag[i] != '"' {
   747				if tag[i] == '\\' {
   748					i++
   749				}
   750				i++
   751			}
   752			if i >= len(tag) {
   753				break
   754			}
   755			qvalue := string(tag[:i+1])
   756			tag = tag[i+1:]
   757	
   758			if key == name {
   759				value, _ := strconv.Unquote(qvalue)
   760				return value
   761			}
   762		}
   763		return ""
   764	}
   765	
   766	// Field returns the i'th struct field.
   767	func (t *structType) Field(i int) (f StructField) {
   768		if i < 0 || i >= len(t.fields) {
   769			return
   770		}
   771		p := t.fields[i]
   772		f.Type = toType(p.typ)
   773		if p.name != nil {
   774			f.Name = *p.name
   775		} else {
   776			t := f.Type
   777			if t.Kind() == Ptr {
   778				t = t.Elem()
   779			}
   780			f.Name = t.Name()
   781			f.Anonymous = true
   782		}
   783		if p.pkgPath != nil {
   784			f.PkgPath = *p.pkgPath
   785		}
   786		if p.tag != nil {
   787			f.Tag = StructTag(*p.tag)
   788		}
   789		f.Offset = p.offset
   790		f.Index = []int{i}
   791		return
   792	}
   793	
   794	// TODO(gri): Should there be an error/bool indicator if the index
   795	//            is wrong for FieldByIndex?
   796	
   797	// FieldByIndex returns the nested field corresponding to index.
   798	func (t *structType) FieldByIndex(index []int) (f StructField) {
   799		f.Type = Type(t.toType())
   800		for i, x := range index {
   801			if i > 0 {
   802				ft := f.Type
   803				if ft.Kind() == Ptr && ft.Elem().Kind() == Struct {
   804					ft = ft.Elem()
   805				}
   806				f.Type = ft
   807			}
   808			f = f.Type.Field(x)
   809		}
   810		return
   811	}
   812	
   813	const inf = 1 << 30 // infinity - no struct has that many nesting levels
   814	
   815	func (t *structType) fieldByNameFunc(match func(string) bool, mark map[*structType]bool, depth int) (ff StructField, fd int) {
   816		fd = inf // field depth
   817	
   818		if mark[t] {
   819			// Struct already seen.
   820			return
   821		}
   822		mark[t] = true
   823	
   824		var fi int // field index
   825		n := 0     // number of matching fields at depth fd
   826	L:
   827		for i := range t.fields {
   828			f := t.Field(i)
   829			d := inf
   830			switch {
   831			case match(f.Name):
   832				// Matching top-level field.
   833				d = depth
   834			case f.Anonymous:
   835				ft := f.Type
   836				if ft.Kind() == Ptr {
   837					ft = ft.Elem()
   838				}
   839				switch {
   840				case match(ft.Name()):
   841					// Matching anonymous top-level field.
   842					d = depth
   843				case fd > depth:
   844					// No top-level field yet; look inside nested structs.
   845					if ft.Kind() == Struct {
   846						st := (*structType)(unsafe.Pointer(ft.(*commonType)))
   847						f, d = st.fieldByNameFunc(match, mark, depth+1)
   848					}
   849				}
   850			}
   851	
   852			switch {
   853			case d < fd:
   854				// Found field at shallower depth.
   855				ff, fi, fd = f, i, d
   856				n = 1
   857			case d == fd:
   858				// More than one matching field at the same depth (or d, fd == inf).
   859				// Same as no field found at this depth.
   860				n++
   861				if d == depth {
   862					// Impossible to find a field at lower depth.
   863					break L
   864				}
   865			}
   866		}
   867	
   868		if n == 1 {
   869			// Found matching field.
   870			if len(ff.Index) <= depth {
   871				ff.Index = make([]int, depth+1)
   872			}
   873			ff.Index[depth] = fi
   874		} else {
   875			// None or more than one matching field found.
   876			fd = inf
   877		}
   878	
   879		mark[t] = false, false
   880		return
   881	}
   882	
   883	// FieldByName returns the struct field with the given name
   884	// and a boolean to indicate if the field was found.
   885	func (t *structType) FieldByName(name string) (f StructField, present bool) {
   886		return t.FieldByNameFunc(func(s string) bool { return s == name })
   887	}
   888	
   889	// FieldByNameFunc returns the struct field with a name that satisfies the
   890	// match function and a boolean to indicate if the field was found.
   891	func (t *structType) FieldByNameFunc(match func(string) bool) (f StructField, present bool) {
   892		if ff, fd := t.fieldByNameFunc(match, make(map[*structType]bool), 0); fd < inf {
   893			ff.Index = ff.Index[0 : fd+1]
   894			f, present = ff, true
   895		}
   896		return
   897	}
   898	
   899	// Convert runtime type to reflect type.
   900	func toCommonType(p *runtime.Type) *commonType {
   901		if p == nil {
   902			return nil
   903		}
   904		type hdr struct {
   905			x interface{}
   906			t commonType
   907		}
   908		x := unsafe.Pointer(p)
   909		if uintptr(x)&reflectFlags != 0 {
   910			panic("reflect: invalid interface value")
   911		}
   912		return &(*hdr)(x).t
   913	}
   914	
   915	func toType(p *runtime.Type) Type {
   916		if p == nil {
   917			return nil
   918		}
   919		return toCommonType(p).toType()
   920	}
   921	
   922	// TypeOf returns the reflection Type of the value in the interface{}.
   923	func TypeOf(i interface{}) Type {
   924		eface := *(*emptyInterface)(unsafe.Pointer(&i))
   925		return toType(eface.typ)
   926	}
   927	
   928	// ptrMap is the cache for PtrTo.
   929	var ptrMap struct {
   930		sync.RWMutex
   931		m map[*commonType]*ptrType
   932	}
   933	
   934	func (t *commonType) runtimeType() *runtime.Type {
   935		// The runtime.Type always precedes the commonType in memory.
   936		// Adjust pointer to find it.
   937		var rt struct {
   938			i  runtime.Type
   939			ct commonType
   940		}
   941		return (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - unsafe.Offsetof(rt.ct)))
   942	}
   943	
   944	// PtrTo returns the pointer type with element t.
   945	// For example, if t represents type Foo, PtrTo(t) represents *Foo.
   946	func PtrTo(t Type) Type {
   947		// If t records its pointer-to type, use it.
   948		ct := t.(*commonType)
   949		if p := ct.ptrToThis; p != nil {
   950			return toType(p)
   951		}
   952	
   953		// Otherwise, synthesize one.
   954		// This only happens for pointers with no methods.
   955		// We keep the mapping in a map on the side, because
   956		// this operation is rare and a separate map lets us keep
   957		// the type structures in read-only memory.
   958		ptrMap.RLock()
   959		if m := ptrMap.m; m != nil {
   960			if p := m[ct]; p != nil {
   961				ptrMap.RUnlock()
   962				return p.commonType.toType()
   963			}
   964		}
   965		ptrMap.RUnlock()
   966		ptrMap.Lock()
   967		if ptrMap.m == nil {
   968			ptrMap.m = make(map[*commonType]*ptrType)
   969		}
   970		p := ptrMap.m[ct]
   971		if p != nil {
   972			// some other goroutine won the race and created it
   973			ptrMap.Unlock()
   974			return p
   975		}
   976	
   977		var rt struct {
   978			i runtime.Type
   979			ptrType
   980		}
   981		rt.i = (*runtime.PtrType)(unsafe.Pointer(&rt.ptrType))
   982	
   983		// initialize p using *byte's ptrType as a prototype.
   984		// have to do assignment as ptrType, not runtime.PtrType,
   985		// in order to write to unexported fields.
   986		p = &rt.ptrType
   987		bp := (*ptrType)(unsafe.Pointer(unsafe.Typeof((*byte)(nil)).(*runtime.PtrType)))
   988		*p = *bp
   989	
   990		s := "*" + *ct.string
   991		p.string = &s
   992	
   993		// For the type structures linked into the binary, the
   994		// compiler provides a good hash of the string.
   995		// Create a good hash for the new string by using
   996		// the FNV-1 hash's mixing function to combine the
   997		// old hash and the new "*".
   998		p.hash = ct.hash*16777619 ^ '*'
   999	
  1000		p.uncommonType = nil
  1001		p.ptrToThis = nil
  1002		p.elem = (*runtime.Type)(unsafe.Pointer(uintptr(unsafe.Pointer(ct)) - unsafe.Offsetof(rt.ptrType)))
  1003	
  1004		ptrMap.m[ct] = p
  1005		ptrMap.Unlock()
  1006		return p.commonType.toType()
  1007	}
  1008	
  1009	func (t *commonType) Implements(u Type) bool {
  1010		if u == nil {
  1011			panic("reflect: nil type passed to Type.Implements")
  1012		}
  1013		if u.Kind() != Interface {
  1014			panic("reflect: non-interface type passed to Type.Implements")
  1015		}
  1016		return implements(u.(*commonType), t)
  1017	}
  1018	
  1019	func (t *commonType) AssignableTo(u Type) bool {
  1020		if u == nil {
  1021			panic("reflect: nil type passed to Type.AssignableTo")
  1022		}
  1023		uu := u.(*commonType)
  1024		return directlyAssignable(uu, t) || implements(uu, t)
  1025	}
  1026	
  1027	// implements returns true if the type V implements the interface type T.
  1028	func implements(T, V *commonType) bool {
  1029		if T.Kind() != Interface {
  1030			return false
  1031		}
  1032		t := (*interfaceType)(unsafe.Pointer(T))
  1033		if len(t.methods) == 0 {
  1034			return true
  1035		}
  1036	
  1037		// The same algorithm applies in both cases, but the
  1038		// method tables for an interface type and a concrete type
  1039		// are different, so the code is duplicated.
  1040		// In both cases the algorithm is a linear scan over the two
  1041		// lists - T's methods and V's methods - simultaneously.
  1042		// Since method tables are stored in a unique sorted order
  1043		// (alphabetical, with no duplicate method names), the scan
  1044		// through V's methods must hit a match for each of T's
  1045		// methods along the way, or else V does not implement T.
  1046		// This lets us run the scan in overall linear time instead of
  1047		// the quadratic time  a naive search would require.
  1048		// See also ../runtime/iface.c.
  1049		if V.Kind() == Interface {
  1050			v := (*interfaceType)(unsafe.Pointer(V))
  1051			i := 0
  1052			for j := 0; j < len(v.methods); j++ {
  1053				tm := &t.methods[i]
  1054				vm := &v.methods[j]
  1055				if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.typ == tm.typ {
  1056					if i++; i >= len(t.methods) {
  1057						return true
  1058					}
  1059				}
  1060			}
  1061			return false
  1062		}
  1063	
  1064		v := V.uncommon()
  1065		if v == nil {
  1066			return false
  1067		}
  1068		i := 0
  1069		for j := 0; j < len(v.methods); j++ {
  1070			tm := &t.methods[i]
  1071			vm := &v.methods[j]
  1072			if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.mtyp == tm.typ {
  1073				if i++; i >= len(t.methods) {
  1074					return true
  1075				}
  1076			}
  1077		}
  1078		return false
  1079	}
  1080	
  1081	// directlyAssignable returns true if a value x of type V can be directly
  1082	// assigned (using memmove) to a value of type T.
  1083	// http://golang.org/doc/go_spec.html#Assignability
  1084	// Ignoring the interface rules (implemented elsewhere)
  1085	// and the ideal constant rules (no ideal constants at run time).
  1086	func directlyAssignable(T, V *commonType) bool {
  1087		// x's type V is identical to T?
  1088		if T == V {
  1089			return true
  1090		}
  1091	
  1092		// Otherwise at least one of T and V must be unnamed
  1093		// and they must have the same kind.
  1094		if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() {
  1095			return false
  1096		}
  1097	
  1098		// x's type T and V have identical underlying types.
  1099		// Since at least one is unnamed, only the composite types
  1100		// need to be considered.
  1101		switch T.Kind() {
  1102		case Array:
  1103			return T.Elem() == V.Elem() && T.Len() == V.Len()
  1104	
  1105		case Chan:
  1106			// Special case:
  1107			// x is a bidirectional channel value, T is a channel type,
  1108			// and x's type V and T have identical element types.
  1109			if V.ChanDir() == BothDir && T.Elem() == V.Elem() {
  1110				return true
  1111			}
  1112	
  1113			// Otherwise continue test for identical underlying type.
  1114			return V.ChanDir() == T.ChanDir() && T.Elem() == V.Elem()
  1115	
  1116		case Func:
  1117			t := (*funcType)(unsafe.Pointer(T))
  1118			v := (*funcType)(unsafe.Pointer(V))
  1119			if t.dotdotdot != v.dotdotdot || len(t.in) != len(v.in) || len(t.out) != len(v.out) {
  1120				return false
  1121			}
  1122			for i, typ := range t.in {
  1123				if typ != v.in[i] {
  1124					return false
  1125				}
  1126			}
  1127			for i, typ := range t.out {
  1128				if typ != v.out[i] {
  1129					return false
  1130				}
  1131			}
  1132			return true
  1133	
  1134		case Interface:
  1135			t := (*interfaceType)(unsafe.Pointer(T))
  1136			v := (*interfaceType)(unsafe.Pointer(V))
  1137			if len(t.methods) == 0 && len(v.methods) == 0 {
  1138				return true
  1139			}
  1140			// Might have the same methods but still
  1141			// need a run time conversion.
  1142			return false
  1143	
  1144		case Map:
  1145			return T.Key() == V.Key() && T.Elem() == V.Elem()
  1146	
  1147		case Ptr, Slice:
  1148			return T.Elem() == V.Elem()
  1149	
  1150		case Struct:
  1151			t := (*structType)(unsafe.Pointer(T))
  1152			v := (*structType)(unsafe.Pointer(V))
  1153			if len(t.fields) != len(v.fields) {
  1154				return false
  1155			}
  1156			for i := range t.fields {
  1157				tf := &t.fields[i]
  1158				vf := &v.fields[i]
  1159				if tf.name != vf.name || tf.pkgPath != vf.pkgPath ||
  1160					tf.typ != vf.typ || tf.tag != vf.tag || tf.offset != vf.offset {
  1161					return false
  1162				}
  1163			}
  1164			return true
  1165		}
  1166	
  1167		return false
  1168	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.