A struct groups related fields into one Go value. Use one when application data has a known shape, such as configuration settings or a JSON response. Fields can hold basic types, slices, pointers, or other custom types. section 3.1.1 section 2.2.1
Choose the form that fits the data’s lifetime and use:
- Define a named type when the structure will be reused. Capitalize fields that another package, such as encoding/json, must access. section 3.1.1 section 3.1.5
- Declare an anonymous struct inline for one-off data or compact test cases. section 3.1.1
- Place another custom type in a field to compose related data; attach methods when behavior belongs with the type. section 3.1.1 section 3.5
Map a JSON response to a struct
When the response shape is known, define its fields and decode into a value: package main import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name"` } func main() { var p Person if err := json.Unmarshal([]byte(`{"name":"Miracle Max"}`), &p); err != nil { fmt.Println(err) return } fmt.Println(p.Name) } The tag maps the JSON key to the exported Go field. If the response structure is unknown or varies, decoding into an interface{} is an alternative, but accessing values then requires inspecting their types. section 11.3 section 3.1.5
Listing 2.9 Parsing a JSON configuration file: json_config.go
package main
import (
"encoding/json"
"fmt"
"os"
)
type configuration struct { #1
Enabled bool #1
Path string #1
} #1
func main() {
file, err := os.Open("config.json") #2
if err != nil {
panic(err)
}
defer file.Close()
decoder := json.NewDecoder(file) #3
conf := configuration{} #3
err = decoder.Decode(&conf) #3
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println(conf.Path)
}
A configuration parser shows the same mapping in a file-backed application: define a struct matching the JSON, decode into its address, then use its fields. section 2.2.1
Structs also work with interfaces and methods to express object-like behavior without an inheritance hierarchy. A method uses a receiver to access its type’s data; a pointer receiver can modify that data. When field names or values must be discovered at runtime instead, reflect.Type and reflect.Value can walk a struct, including nested fields. section 3.2 section 13.1.3













