反射包主要有一个接口:type,和一个结构value;

type接口

commonType类型实现了type接口,下面是type中的各类型关系

  • commonType>unCommonType>method
  • arrayType|chanType|funcType|interfaceType|mapType|ptrType|sliceType >commonType
  • ptrMap>n*commonType

其他结构

Method结构

MethodByName()和Method()会返回这种类型

type Method struct {
	Name    string
	PkgPath string

	Type  Type  // method type
	Func  Value // func with receiver as first argument
	Index int   // index for Type.Method
}

structField结构

Field()和FieldByIndex(),以及FieldByName(),FieldByNameFunc会返回该类型

type structField struct {
	name    *string      // nil for embedded fields
	pkgPath *string      // nil for exported Names; otherwise import path
	typ     *runtimeType // type of field
	tag     *string      // nil if no tag
	offset  uintptr      // byte offset of field within struct
}

反射一个变量的type,本质上是将这个变量的指针转换为commonType的指针

  • 首先将变量的指针,通过unsafe包将类型转换为Pointer类型
  • 然后将Pointer类型转换为*emptyInterface类型,并使用*表达式将其emptyInterface的值传给eface
  • 断言eface.typ的值是否是commonType的指针类型,如果是则返回其值
func toType(p *runtimeType) Type {
	if p == nil {
		return nil
	}
	return (*p).(*commonType)
}

func TypeOf(i interface{}) Type {
	eface := *(*emptyInterface)(unsafe.Pointer(&i))
	return toType(eface.typ)
}

类型函数介绍

func ChanOf(dir ChanDir, t Type) Type
返回channel type
func MapOf(key, elem Type) Type
返回Map type
func PtrTo(t Type) Type
返回指针类型
func SliceOf(t Type) Type
返回slice类型
func TypeOf(i interface{}) Type
反射变量类型,最好不要直接传指针进去.否则会有些东西发射不出.例如Name()

type类型方法介绍

			type B struct {
				c string
				b byte
				a int
			}

			func (b B) test() {

			}

			func main() {
				b := B{}
				fmt.Println(reflect.TypeOf(b).Method(0).Name)  //test
			}
		
			type B struct {
				c string
				b byte
				a int
			}

			func (b B) test() {

			}

			func main() {
				b := new(B)
				m, _ := reflect.TypeOf(b).MethodByName("test")
				fmt.Println(m.PkgPath)
			}
		
			type B struct {
				c string
				b byte
				a int
			}

			func (b B) test() {

			}

			func test(a ...int) {

			}

			func main() {
				fmt.Println(reflect.TypeOf(test).IsVariadic())     //true
				fmt.Println(reflect.TypeOf(B.test).IsVariadic())   //false
			}
		
		type B struct {
			c string
			b byte
			a int
		}

		func (b B) test() {

		}

		func main() {
			b := &B{}
			fmt.Println(reflect.TypeOf(b).Elem())   //main.B
		}
	
			type A struct {
				a int
				b byte
				c string
			}

			type B struct {
				A
				c string
				b byte
				a int
			}

			func (b B) test() {

			}

			func main() {
				b := B{}
				index := []int{0, 1}
				fmt.Println(reflect.TypeOf(b).FieldByIndex(index).Name)   //b
			}
		
	type B struct {
		c string
		b byte
		a int
	}

	func test(a string) bool {

		return true
	}
	func main() {
		b := B{}

		fmt.Println(reflect.TypeOf(b).FieldByNameFunc(test))  //{    0 [] false} false
	}	
	
		func test(a string) bool {
			return true
		}
		func main() {

			fmt.Println(reflect.TypeOf(test).In(0))
		}
	

题外话:声明变量其值为匿名结构

type T struct {}
var t T
var t struct {}