file: src/reflect/type.go // A StructField describes a single field in a struct. type StructField struct { // Name is the field name. Name string // PkgPath is the package path that qualifies a lower case (unexported) // field name. It is empty for upper case (exported) field names. // See https://golang.org/ref/spec#Uniqueness_of_identifiers PkgPath string Type Type // field type Tag StructTag // field tag string Offset uintptr// offset within struct, in bytes Index []int// index sequence for Type.FieldByIndex Anonymous bool// is an embedded field }
funcMethod(in interface{})(ok bool) { v := reflect.ValueOf(in) if v.Kind() == reflect.Slice { ok = true } else { //panic } num := v.Len() for i := 0; i < num; i++ { fmt.Println(v.Index(i).Interface()) } return ok }
funcmain() { s := []int{1, 3, 5, 7, 9} b := []float64{1.2, 3.4, 5.6, 7.8} Method(s) Method(b) }
funcValueOf(i interface{})Value { if i == nil { return Value{} } // TODO(rsc): Eliminate this terrible hack. // In the call to unpackEface, i.typ doesn't escape, // and i.word is an integer. So it looks like // i doesn't escape. But really it does, // because i.word is actually a pointer. escapes(i) return unpackEface(i) }
// unpackEface converts the empty interface i to a 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 //too much comment, delete it flag } ... funcunpackEface(i interface{})Value { e := (*emptyInterface)(unsafe.Pointer(&i)) // NOTE: don't read e.word until we know whether it is really a pointer or not. t := e.typ if t == nil { return Value{} } f := flag(t.Kind()) if ifaceIndir(t) { f |= flagIndir } return Value{t, unsafe.Pointer(e.word), f} }
Value struct结构是核心,rtype是数据的底层实现,flag是元数据,可用用来表征Value的数据类型。unpackEface是把interface{}转换成Value数据。代码中ifaceIndir()用来确定是不是指针。 我们上面代码中还出现了Kind(),Kind()内不是实现的是kind(),从下面代码可以看出主要就是一个&的运算。这里还有个一个小细节。1<<flagKindWidth - 1在这里的结果为(1<<flagKindWidth) - 1,而C语言中的结果为1<<(flagKindWidth-1)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
const ( flagKindWidth = 5// there are 27 kinds flagKindMask flag = 1<<flagKindWidth - 1 flagStickyRO flag = 1 << 5 flagEmbedRO flag = 1 << 6 flagIndir flag = 1 << 7 flagAddr flag = 1 << 8 flagMethod flag = 1 << 9 flagMethodShift = 10 flagRO flag = flagStickyRO | flagEmbedRO )