Skip to content

Golang struct tags ​

Preface ​

In Golang, by properly using struct tags, related processing of additional language features can be achieved, through json:",string" Numbers can be converted to strings during encoding or decoding; through json:",omitempty" When a field's value is zero, the field can be ignored after encoding. In the JSON data, you won't see the field at all—it's as if it never existed!

General label format ​

go
type Example struct {
  FieldName Type `tag1:"value1" tag2:"value2" tag3:"value3,option1,option2"`
}

1. JSON tag ​

Basic usage ​

go
type User struct {
  ID       int    `json:"id"`               // The field name is "id"
  Name     string `json:"name"`             // The field name is "name"
  Password string `json:"-"`                // Ignore this field
}

Advanced Options ​

go
type Product struct {
  ID          int      `json:"id"`
  Name        string   `json:"name,omitempty"`      // Ignore when empty
  Price       float64  `json:"price,string"`        // Convert number to string
  Tags        []string `json:"tags,omitempty"`      // Ignore when the slice is empty
  CreatedAt   time.Time `json:"created_at"`
  IsAvailable bool     `json:"is_available"`

  // Complex option combinations
  Score       float64  `json:"score,omitempty,string"` // Multiple options
}

Option description: ​

  • omitempty- Ignore this field when the value is zero

  • string- Encode numbers/booleans as strings

  • -- Completely ignore this field

2. MapStructure tag ​

Basic usage (for configuration parsing such as Viper) ​

go
type Config struct {
  ServerHost string `mapstructure:"server_host"`    // Map underscore naming
  ServerPort int    `mapstructure:"server_port"`
}

Embedded struct handling ​

go
type BaseConfig struct {
  Name string `mapstructure:"name"`
  Env  string `mapstructure:"env"`
}

type ServiceConfig struct {
  BaseConfig `mapstructure:",squash"`  // Key: Flatten embedded structs
  Timeout    time.Duration `mapstructure:"timeout"`
}

Special options: ​

  • ,squash- Flatten the fields of embedded structs

  • ,remain- Collect unmapped fields into a map

  • -- Ignore field

3. YAML tags ​

Basic usage ​

go
type Config struct {
  Host     string   `yaml:"host"`
  Port     int      `yaml:"port,omitempty"`
  Features []string `yaml:"features,flow"`  // Inline array format
}

Streaming style options ​

go
type Deployment struct {
  Replicas int      `yaml:"replicas"`
  Images   []string `yaml:"images,flow"`    // Output is: images: [a, b, c]
}

GORM tags ​

go
type User struct {
  gorm.Model
  Name     string `gorm:"type:varchar(100);not null;uniqueIndex"`
  Email    string `gorm:"type:varchar(255);unique;index:idx_email"`
  Age      int    `gorm:"default:18;check:age > 0"`
  Status   string `gorm:"type:enum('active','inactive');default:'active'"`
}

XORM tag ​

go
type Product struct {
  ID       int64  `xorm:"pk autoincr 'product_id'"`
  Name     string `xorm:"varchar(100) notnull index"`
  Price    float64 `xorm:"decimal(10,2) default 0.00"`
  IsActive bool   `xorm:"default true"`
}

5. Verification Label ​

validator.v9/v10 ​

go
type User struct {
  ID       int    `validate:"required,gt=0"`
  Name     string `validate:"required,min=2,max=50"`
  Email    string `validate:"required,email"`
  Age      int    `validate:"gte=0,lte=150"`
  Password string `validate:"required,min=8"`
  Website  string `validate:"url"`
  IP       string `validate:"ip"`
}

Gin binding validation ​

go
type LoginRequest struct {
  Username string `json:"username" binding:"required,alphanum,min=3,max=20"`
  Password string `json:"password" binding:"required,min=8"`
  Email    string `json:"email" binding:"omitempty,email"`
}

6. XML tags ​

go
type Person struct {
  XMLName   xml.Name `xml:"person"`
  ID        int      `xml:"id,attr"`           // As an attribute
  FirstName string   `xml:"name>first"`        // nested elements
  LastName  string   `xml:"name>last"`
  Age       int      `xml:"age"`
  Bio       string   `xml:",chardata"`         // Character data
  Comment   string   `xml:",comment"`          // 注释
}

7. Form tags (used for HTTP forms) ​

go
type LoginForm struct {
  Username string `form:"username" binding:"required"`
  Password string `form:"password" binding:"required"`
  Remember bool   `form:"remember_me"`
}

8. Environment Variable Tags ​

envconfig ​

go
type Config struct {
  DatabaseURL string `envconfig:"DATABASE_URL" required:"true"`
  Port        int    `envconfig:"PORT" default:"8080"`
  Debug       bool   `envconfig:"DEBUG" default:"false"`
}

9. Protocol Buffer tags ​

go
type User struct {
  ID       int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
  Name     string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
  Email    string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
}

10. Custom Tags ​

Custom parsing ​

go
type Config struct {
  Host     string `custom:"host;required;default=localhost"`
  Port     int    `custom:"port;min=1;max=65535"`
  Timeout  time.Duration `custom:"timeout;unit=second"`
}

// Custom parsing function
func ParseCustomTag(tag string) map[string]string {
  // Parsing logic
}

Comprehensive example ​

go
type AppConfig struct {
  // JSON serialization
  Name string `json:"name" yaml:"name" mapstructure:"name"`
  // Database mapping
  DatabaseURL string `json:"database_url" mapstructure:"database_url" envconfig:"DATABASE_URL"`
  // Validation rules
  Port int `json:"port" mapstructure:"port" validate:"required,gt=0,lte=65535"`
  // Ignore field
  SecretKey string `json:"-" mapstructure:"secret_key" yaml:"-"`
  // time format
  CreatedAt time.Time `json:"created_at" mapstructure:"created_at" time_format:"2006-01-02"`
  // embedded struct
  BaseConfig `mapstructure:",squash" json:",inline" yaml:",inline"`
}

type BaseConfig struct {
  Environment string `json:"environment" mapstructure:"environment"`
  Version     string `json:"version" mapstructure:"version"`
}

Best practices ​

  • Consistency: Maintain consistency in label naming throughout the entire project

  • Clarity: Use explicit field name mapping to avoid ambiguity

  • 安全性: Sensitive field usage json:"-" Avoid serialization

  • Verification: Combine validation tags to ensure data integrity

  • document: Add explanatory comments for complex tag combinations

Common Issue Resolution ​

Viper embedded struct issue ​

go
// Error: embedded struct field cannot be mapped
type ServiceConfig struct {
  ServiceConfig
  Timeout time.Duration
}

// Correct: use squash
type ServiceConfig struct {
  ServiceConfig `mapstructure:",squash"`
  Timeout time.Duration `mapstructure:"timeout"`
}

Null value handling ​

go
// Avoid outputting null fields
type Config struct {
  OptionalField string `json:"optional_field,omitempty"`
  EmptyArray    []string `json:"empty_array,omitempty"`
}

This way, you can comprehensively master the various uses of Go struct tags!

Last updated on11/07/2026, 02:16 PM
@fishfinal | @fishfinals | [email protected]