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

sample
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)
}
  1. 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
  1. 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
  1. 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