Reflection Basics
Type and Kind
Reflection can inspect the runtime type and broad kind of a value.
type and kind
`reflect.TypeOf` reports the concrete type, while `Kind` groups types into categories like string, int, struct, and slice.
Type and Kind
type_kind.go
Replay: real traced execution (multi-file project)
package main
import (
"fmt"
"reflect"
)
func main() {
var sample = "go"
valueType := reflect.TypeOf(sample)
kind := valueType.Kind()
size := valueType.Size()
fmt.Println("sample=", sample)
fmt.Println("type=", valueType.String())
fmt.Println("kind=", kind.String())
fmt.Println("size=", size)
}
package main
import (
"fmt"
"reflect"
)
func main() {
var sample = "trace"
valueType := reflect.TypeOf(sample)
kind := valueType.Kind()
size := valueType.Size()
fmt.Println("sample=", sample)
fmt.Println("type=", valueType.String())
fmt.Println("kind=", kind.String())
fmt.Println("size=", size)
}
package main
import (
"fmt"
"reflect"
)
func main() {
var sample = "book"
valueType := reflect.TypeOf(sample)
kind := valueType.Kind()
size := valueType.Size()
fmt.Println("sample=", sample)
fmt.Println("type=", valueType.String())
fmt.Println("kind=", kind.String())
fmt.Println("size=", size)
}
sample ← "go", valueType ← &reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}
8func main() {9 var sample→ "go" = "go" //@sample="trace", "book"10 valueType→ &reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}} := reflect.TypeOf(sample"go")11 kind→ 0x18 := valueType&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}.Kind()12 size→ 0x10 := valueType&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}.Size()1314 fmt.Println("sample=", sample"go")15 fmt.Println("type=", valueType&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}.String())16 fmt.Println("kind=", kind0x18.String())17 fmt.Println("size=", size0x10)18}outputsample= go type= string kind= string size= 16
sample ← "trace", valueType ← &reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}
8func main() {9 var sample→ "trace" = "trace"10 valueType→ &reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}} := reflect.TypeOf(sample"trace")11 kind→ 0x18 := valueType&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}.Kind()12 size→ 0x10 := valueType&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}.Size()1314 fmt.Println("sample=", sample"trace")15 fmt.Println("type=", valueType&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}.String())16 fmt.Println("kind=", kind0x18.String())17 fmt.Println("size=", size0x10)18}outputsample= trace type= string kind= string size= 16
sample ← "book", valueType ← &reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}
8func main() {9 var sample→ "book" = "book"10 valueType→ &reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}} := reflect.TypeOf(sample"book")11 kind→ 0x18 := valueType&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}.Kind()12 size→ 0x10 := valueType&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}.Size()1314 fmt.Println("sample=", sample"book")15 fmt.Println("type=", valueType&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:3749, PtrToThis:19936}}.String())16 fmt.Println("kind=", kind0x18.String())17 fmt.Println("size=", size0x10)18}outputsample= book type= string kind= string size= 16