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 in Go is a user-defined composite data type that aggregates zero or more named, typed fields into a single contiguous block of memory. It serves as the foundational mechanism for creating complex data structures, providing state encapsulation in a language that does not feature traditional classes.

Declaration Syntax

Structs are defined using the type and struct keywords. Fields of the same type can be grouped on a single line.
type ServerConfig struct {
    Host, Port string // Grouped declaration
    Timeout    int
    tlsEnabled bool   // Unexported field
}

Visibility and Encapsulation

Go uses identifier casing to determine field visibility across package boundaries, which is the primary mechanism for state encapsulation:
  • Exported fields: Begin with an uppercase letter (e.g., Host, Timeout). These fields are accessible from anywhere the struct’s package is imported.
  • Unexported fields: Begin with a lowercase letter (e.g., tlsEnabled). These fields are strictly private to the package in which the struct is defined, preventing external access or modification.

Value Semantics

Structs in Go are value types. Assigning a struct to a new variable or passing it as an argument to a function creates a complete, independent copy of the struct’s data. Because copying large structs can be memory-intensive and prevents functions from modifying the original instance, developers frequently use pointers (*StructType) to share a single struct instance across function boundaries.

Instantiation and Initialization

Structs can be instantiated in several ways, dictating how memory is allocated and initialized.
// 1. Zero-value initialization: Allocates memory and sets all fields to their respective zero values.
var config ServerConfig 

// 2. Named struct literal: Explicitly assigns values to named fields. Unspecified fields default to zero values.
config2 := ServerConfig{
    Host: "localhost",
    Port: "8080",
}

// 3. Positional struct literal: Assigns values based on declaration order. (Brittle, generally discouraged).
config3 := ServerConfig{"localhost", "8080", 30, true}

// 4. Pointer instantiation: Allocates memory and returns a pointer to the struct.
configPtr1 := &ServerConfig{Host: "localhost"}
configPtr2 := new(ServerConfig) // Returns *ServerConfig, zero-valued

Field Access and Implicit Dereferencing

Fields are accessed using dot notation. When accessing fields through a struct pointer, the Go compiler automatically dereferences the pointer; explicit dereferencing ((*ptr).Field) is syntactically valid but idiomatic Go omits it.
config.Timeout = 60

ptr := &config
ptr.Timeout = 120 // Implicitly translated to (*ptr).Timeout = 120

Anonymous Structs

Structs can be declared and instantiated simultaneously without defining a package-level type. This is primarily used for localized, single-use data structures.
response := struct {
    StatusCode int
    Body       string
}{
    StatusCode: 200,
    Body:       "OK",
}

The Empty Struct

An empty struct is a struct type with no fields, declared as struct{}. It is a unique type in Go because it occupies exactly zero bytes of memory. It is the idiomatic mechanism for signaling or representing a lack of data, such as implementing sets via maps or creating zero-allocation signaling channels.
var empty struct{}
// unsafe.Sizeof(empty) == 0

set := make(map[string]struct{})
signal := make(chan struct{})

Recursive Structs

A struct cannot contain a field of its own type as a value. Because structs are value types, a self-referential value field would require infinite memory allocation, resulting in a compile-time error. However, a struct can contain a pointer to its own type, which is the fundamental mechanism for building recursive data structures like linked lists and trees.
type Node struct {
    Value int
    // Next Node // Compile-time error: invalid recursive type
    Next  *Node  // Valid: pointer to the same struct type
}

Struct Embedding and Field Promotion

Go does not support classical inheritance. Instead, it uses composition via struct embedding. If a struct is embedded without a field name (an anonymous field), its fields and methods are “promoted” to the parent struct’s namespace.
type Base struct {
    ID        string
    CreatedAt int64
}

type Record struct {
    Base   // Embedded anonymous field
    Status string
}

r := Record{}
r.ID = "123"       // Promoted access
r.Base.ID = "123"  // Explicit access (equivalent to above)

Struct Tags

Fields can be annotated with string literals known as tags. These tags are ignored by the compiler but can be parsed at runtime using Go’s reflect package. They are the standard mechanism for defining metadata for serialization (JSON, XML) or validation.
type User struct {
    Password string `json:"-"`                       // Ignored by JSON encoder
    Email    string `json:"email" validate:"email"`  // Mapped to "email" key
}

Memory Layout and Alignment

A struct’s fields are laid out in memory in the exact order they are declared. To satisfy CPU alignment requirements, the Go compiler inserts padding bytes between fields. Because of this, the order of fields dictates the total memory footprint of the struct. Grouping fields of similar sizes can reduce padding and optimize memory usage.

Comparability

A struct is strictly comparable (can be evaluated using == and !=, and used as a map key) if and only if all of its fields are comparable. If a struct contains incomparable types—such as slices, maps, or functions—attempting to compare two instances of that struct will result in a compile-time error.
Master Go with Deep Grasping Methodology!Learn More