Struct tags attach metadata that libraries can read through reflection.

struct tags Tags are strings attached to fields. Reflection can read them so encoders and validators can follow naming rules.

Struct Tags

fieldIndex
struct_tags_reflect.go
Replay: real traced execution (multi-file project)
package main

import (
	"fmt"
	"reflect"
)

type Item struct {
	SKU   string `json:"sku"`
	Count int    `json:"count"`
}

func main() {
	var fieldIndex = 0
	itemType := reflect.TypeOf(Item{})
	field := itemType.Field(fieldIndex)
	jsonName := field.Tag.Get("json")

	fmt.Println("field_index=", fieldIndex)
	fmt.Println("field_name=", field.Name)
	fmt.Println("field_type=", field.Type.String())
	fmt.Println("json_name=", jsonName)
}
package main

import (
	"fmt"
	"reflect"
)

type Item struct {
	SKU   string `json:"sku"`
	Count int    `json:"count"`
}

func main() {
	var fieldIndex = 1
	itemType := reflect.TypeOf(Item{})
	field := itemType.Field(fieldIndex)
	jsonName := field.Tag.Get("json")

	fmt.Println("field_index=", fieldIndex)
	fmt.Println("field_name=", field.Name)
	fmt.Println("field_type=", field.Type.String())
	fmt.Println("json_name=", jsonName)
}
  1. fieldIndex ← 0, itemType ← &reflect.rtype{t:abi.Type{Size_:0x18, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x19, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:6798, PtrToThis:19168}}

    13func main() {14  var fieldIndex→ 0 = 0 //@fieldIndex=115  itemType→ &reflect.rtype{t:abi.Type{Size_:0x18, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x19, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:6798, PtrToThis:19168}} := reflect.TypeOf(Item{})16  field→ reflect.StructField{Name:"SKU", PkgPath:"", Type:(*reflect.rtype)(⟨addr D⟩), Tag:"json:\"sku\"", Offset:0x0, Index:[]int{0}, Anonymous:false} := itemType&reflect.rtype{t:abi.Type{Size_:0x18, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x19, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:6798, PtrToThis:19168}}.Field(fieldIndex0)17  jsonName→ "sku" := field.Tag"json:\"sku\"".Get("json")1819  fmt.Println("field_index=", fieldIndex0)20  fmt.Println("field_name=", field.Name"SKU")21  fmt.Println("field_type=", field.Type&reflect.rtype{t:abi.Type{Size_:0x10, PtrBytes:0x8, Hash:⟨addr E⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x18, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr F⟩), GCData:(*uint8)(⟨addr C⟩), Str:3757, PtrToThis:20064}}.String())22  fmt.Println("json_name=", jsonName"sku")23}
    outputfield_index= 0
    field_name= SKU
    field_type= string
    json_name= sku
  1. fieldIndex ← 1, itemType ← &reflect.rtype{t:abi.Type{Size_:0x18, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x19, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:6798, PtrToThis:19168}}

    13func main() {14  var fieldIndex→ 1 = 115  itemType→ &reflect.rtype{t:abi.Type{Size_:0x18, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x19, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:6798, PtrToThis:19168}} := reflect.TypeOf(Item{})16  field→ reflect.StructField{Name:"Count", PkgPath:"", Type:(*reflect.rtype)(⟨addr D⟩), Tag:"json:\"count\"", Offset:0x10, Index:[]int{1}, Anonymous:false} := itemType&reflect.rtype{t:abi.Type{Size_:0x18, PtrBytes:0x8, Hash:⟨addr A⟩, TFlag:0x7, Align_:0x8, FieldAlign_:0x8, Kind_:0x19, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr B⟩), GCData:(*uint8)(⟨addr C⟩), Str:6798, PtrToThis:19168}}.Field(fieldIndex1)17  jsonName→ "count" := field.Tag"json:\"count\"".Get("json")1819  fmt.Println("field_index=", fieldIndex1)20  fmt.Println("field_name=", field.Name"Count")21  fmt.Println("field_type=", field.Type&reflect.rtype{t:abi.Type{Size_:0x8, PtrBytes:0x0, Hash:⟨addr E⟩, TFlag:0xf, Align_:0x8, FieldAlign_:0x8, Kind_:0x2, Equal:(func(unsafe.Pointer, unsafe.Pointer) bool)(⟨addr F⟩), GCData:(*uint8)(⟨addr G⟩), Str:814, PtrToThis:20640}}.String())22  fmt.Println("json_name=", jsonName"count")23}
    outputfield_index= 1
    field_name= Count
    field_type= int
    json_name= count