Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A struct tag is a string literal metadata annotation attached to a field within a Go struct declaration. It provides declarative, runtime-accessible configuration for that specific field, which can be inspected and parsed using Go’s reflect package. Struct tags are evaluated at compile time and become an intrinsic part of the struct’s type signature. Consequently, two structs with identical fields but different tags are evaluated by the Go compiler as distinct types, though they remain explicitly convertible.

Syntax and Convention

While a struct tag can technically be any string, the Go standard library enforces a strict convention for parsing. Tags are typically written using raw string literals (backticks) to avoid escaping double quotes. The conventional format is a space-separated list of key:"value" pairs.
type Entity struct {
    // Standard convention: key:"value"
    FieldOne string `key1:"value1" key2:"value2"`
    
    // Values often contain comma-separated options
    FieldTwo int    `key:"value,option1,option2"`
    
    // Technically valid, but breaks reflect.StructTag parsing conventions
    FieldThree bool "raw string without standard formatting"
}
Strict Formatting Rules:
  • Keys: Must be unquoted strings consisting of non-control characters, excluding spaces, quotes, and colons.
  • Values: Must be enclosed in double quotes "".
  • Spacing: There must be no space between the key, the colon, and the value. key: "value" is syntactically invalid for standard parsing. Multiple key-value pairs are separated by a single space.

Reflection and Parsing Mechanics

At runtime, struct tags are exposed via the reflect.StructField type, specifically within its Tag field. This field is of type reflect.StructTag, which is a defined type whose underlying type is string (declared as type StructTag string). Because it is a defined type rather than a type alias, it possesses its own method set. The reflect.StructTag type provides two primary methods for extracting metadata:
  1. Get(key string) string: Returns the value associated with the key. If the key does not exist, or if the tag is malformed, it returns an empty string.
  2. Lookup(key string) (value string, ok bool): Returns the value and a boolean indicating whether the key was explicitly present. This is necessary to distinguish between a key that is missing and a key that is explicitly set to an empty string (key:"").
package main

import (
    "fmt"
    "reflect"
)

type Configuration struct {
    Timeout int `env:"TIMEOUT" default:""`
}

func main() {
    // 1. Obtain the reflect.Type of the struct
    t := reflect.TypeOf(Configuration{})

    // 2. Retrieve the specific reflect.StructField
    field, _ := t.FieldByName("Timeout")

    // 3. Access the reflect.StructTag
    tag := field.Tag

    // Using Get()
    envVal := tag.Get("env")
    fmt.Printf("Env Key: %s\n", envVal) 
    // Output: Env Key: TIMEOUT

    // Using Lookup() to differentiate empty vs. missing
    defaultVal, defaultExists := tag.Lookup("default")
    fmt.Printf("Default Exists: %t, Value: %q\n", defaultExists, defaultVal) 
    // Output: Default Exists: true, Value: ""

    missingVal, missingExists := tag.Lookup("unknown")
    fmt.Printf("Unknown Exists: %t, Value: %q\n", missingExists, missingVal) 
    // Output: Unknown Exists: false, Value: ""
}
Because struct tags are parsed dynamically at runtime via reflection, malformed tags (e.g., missing quotes, rogue spaces) do not trigger compile-time errors. Instead, they silently fail during Get or Lookup operations. To mitigate this, developers rely on static analysis tools like go vet to validate struct tag formatting during the build process.
Master Go with Deep Grasping Methodology!Learn More