Question
How can I initialize the nested Proxy struct inside a Go Configuration struct using a struct literal?
package main
type Configuration struct {
Val string
Proxy struct {
Address string
Port string
}
}
func main() {
c := &Configuration{
Val: "test",
Proxy: {
Address: "addr",
Port: "80",
},
}
_ = c
}
The Proxy field is an anonymous nested struct. What is the correct syntax for providing its Address and Port values?
Short Answer
You will learn how Go struct literals initialize nested fields, why anonymous nested structs need their full type in a literal, and when defining a separate named struct type makes code easier to maintain.
Concept
A struct groups related values into one type. A struct can contain another struct as one of its fields, which is often called a nested struct.
In this example, Configuration has a Proxy field. Proxy is not a string or number: its value must be a struct with Address and Port fields.
type Configuration struct {
Val string
Proxy struct {
Address string
Port string
}
}
The inner type is anonymous because it has no name such as ProxyConfig. Go still knows its exact structure, but when you create a value for it in a struct literal, you must state that structure explicitly.
This matters because Go requires every composite literal to identify the type being created. Writing only { ... } is not valid Go syntax: braces alone do not tell the compiler which type should be constructed.
For small, one-off groupings, an anonymous nested struct can be acceptable. For reusable or meaningful concepts such as proxy, database, server, or user settings, a named type is usually clearer.
Mental Model
Think of Configuration as a labelled box containing two compartments:
Valholds one text value.Proxyholds a smaller box with its own labels:AddressandPort.
When filling the smaller box, Go asks you to identify what kind of box it is. With an anonymous struct, you describe the box shape again:
struct {
Address string
Port string
}{
Address: "addr",
Port: "80",
}
If you give that smaller box a name, such as ProxyConfig, you can use the name instead of repeating its shape.
Syntax and Examples
A struct literal uses the form:
TypeName{
FieldName: value,
}
For an anonymous nested struct, specify the nested struct type before its literal:
package main
import "fmt"
type Configuration struct {
Val string
Proxy struct {
Address string
Port string
}
}
func main() {
c := Configuration{
Val: "test",
Proxy: struct {
Address string
Port string
}{
Address: "addr",
Port: "80",
},
}
fmt.Println(c.Proxy.Address) // addr
}
The type written after Proxy: must match the field's type exactly. The field names, their types, and their order must be the same.
A more maintainable approach is to name the inner type:
package main
import "fmt"
type ProxyConfig struct {
Address string
Port string
}
type Configuration struct {
Val string
Proxy ProxyConfig
}
func main() {
c := Configuration{
Val: "test",
Proxy: ProxyConfig{
Address: "addr",
Port: "80",
},
}
fmt.Println(c.Proxy.Port) // 80
}
Using ProxyConfig{...} is shorter, easier to read, and reusable in other parts of the program.
Step by Step Execution
Consider this named-type version:
type ProxyConfig struct {
Address string
Port string
}
type Configuration struct {
Val string
Proxy ProxyConfig
}
func main() {
c := Configuration{
Val: "test",
Proxy: ProxyConfig{
Address: "127.0.0.1",
Port: "8080",
},
}
address := c.Proxy.Address
println(address)
}
Execution proceeds as follows:
ProxyConfigdefines a type withAddressandPortstring fields.Configurationdefines aValstring and aProxyfield whose type isProxyConfig.Configuration{...}creates oneConfigurationvalue.Val: "test"assigns the outerValfield.Proxy: ProxyConfig{...}creates a separateProxyConfigvalue and assigns it to the outerProxyfield.c.Proxy.Addressfirst accesses the nestedProxyvalue, then reads itsAddressfield.- The program prints
127.0.0.1.
If you write c := &Configuration{...}, Go creates a Configuration value and returns a pointer to it. Field access remains the same: c.Proxy.Address. Go automatically dereferences the pointer for this access.
Real World Use Cases
Nested structs are useful when values naturally belong together.
- Application configuration: Group HTTP server settings, database credentials, logging options, and proxy settings.
- API responses: Model nested JSON such as an order that contains customer and shipping-address objects.
- HTTP clients: Keep proxy address, port, credentials, and timeout settings together.
- Domain models: Represent an employee with nested contact information or an invoice with nested billing details.
- Deployment settings: Organize service configuration into sections such as
Database,Cache, andTLS.
For example, a web service may use:
type ServerConfig struct {
Host string
Port int
}
type AppConfig struct {
Environment string
Server ServerConfig
}
This makes config.Server.Port self-explanatory and keeps related settings together.
Real Codebase Usage
In production Go code, developers usually prefer named nested types when the inner data has a real purpose or is used in more than one place.
type DatabaseConfig struct {
Host string
Port int
Name string
User string
Password string
}
type AppConfig struct {
Debug bool
Database DatabaseConfig
}
Common patterns include:
- Configuration loading: Decode JSON, YAML, or environment-derived values into nested configuration structs.
- Validation: Validate nested settings before starting an application.
- Defaults: Build a complete configuration value, then overwrite selected nested fields.
- Dependency injection: Pass a small, focused config type such as
DatabaseConfigto code that only needs database settings. - API models: Use nested types to match the structure of request and response data.
A validation function can use guard clauses for invalid nested values:
func (c Configuration) Validate() error {
if c.Proxy.Address == "" {
return fmt.Errorf("proxy address is required")
}
if c.Proxy.Port == "" {
return fmt.Errorf("proxy port is required")
}
return nil
}
For configuration types shared across packages or reused in tests, a named type is generally preferable to repeating an anonymous struct definition.
Common Mistakes
Omitting the nested type
This does not compile:
c := Configuration{
Proxy: {
Address: "addr",
Port: "80",
},
}
Go does not support an untyped {...} literal. For an anonymous nested struct, include the complete type:
Proxy: struct {
Address string
Port string
}{
Address: "addr",
Port: "80",
},
Using a type that does not match exactly
This also fails because Port has a different type:
Proxy: struct {
Address string
Port int
}{
Address: "addr",
Port: 80,
},
The anonymous type must exactly match the field declaration. Alternatively, define a named type once and reuse it.
Forgetting commas in multiline literals
Go requires a trailing comma after each element in a multiline struct literal:
c := Configuration{
Val: "test", // comma required
}
Confusing a value field with a pointer field
If the field is Proxy ProxyConfig, assign a value with ProxyConfig{...}. If it is Proxy *ProxyConfig, assign a pointer with &ProxyConfig{...}.
type Configuration struct {
Proxy *ProxyConfig
}
c := Configuration{
Proxy: &ProxyConfig{Address: "addr", Port: "80"},
}
Overusing anonymous structs
Anonymous structs are valid, but repeating their definition makes code harder to change. Name the type when it represents a meaningful concept, such as ProxyConfig.
Comparisons
| Approach | Example | Best for | Trade-off |
|---|---|---|---|
| Anonymous nested struct | Proxy struct { Address string; Port string } | Small, local, one-off data shapes | Literal must repeat the full type |
| Named nested struct | Proxy ProxyConfig | Reusable, meaningful configuration or domain data | Requires one additional type declaration |
| Nested struct value | Proxy ProxyConfig | A proxy is always present; zero values are acceptable | Cannot represent absence without another flag or convention |
| Nested struct pointer | Proxy *ProxyConfig | Proxy settings are optional or may be absent | Must handle nil safely |
A named type is often the clearest choice:
type ProxyConfig struct {
Address string
Port string
}
Use an anonymous type mainly when the structure is tightly tied to one containing type and is unlikely to be reused.
Cheat Sheet
// Anonymous nested struct field
type Configuration struct {
Proxy struct {
Address string
Port string
}
}
// Initialize an anonymous nested struct
c := Configuration{
Proxy: struct {
Address string
Port string
}{
Address: "addr",
Port: "80",
},
}
// Preferred for reusable concepts
type ProxyConfig struct {
Address string
Port string
}
type Configuration struct {
Proxy ProxyConfig
}
c := Configuration{
Proxy: ProxyConfig{
Address: "addr",
Port: "80",
},
}
- Use
Field: valuefor keyed struct literals. - Multiline literals need trailing commas.
- Anonymous struct types must match exactly.
- Use
&Configuration{...}when you need a pointer to the outer struct. - Use
*ProxyConfigand&ProxyConfig{...}only when the nested field should be optional or shared.
FAQ
Why does Proxy: { ... } fail in Go?
A composite literal needs a type. { ... } alone has no type, so Go cannot determine what value to create.
Can Go infer the anonymous nested struct type from the field?
No. In a struct literal, Go requires the explicit anonymous struct type for that nested literal.
Should I use an anonymous struct or a named struct type?
Use a named type when the nested data represents a concept, might be reused, needs methods, or should be easier to read. Use an anonymous struct for small, local shapes.
How do I access a field in a nested struct?
Use dot notation for each level:
address := c.Proxy.Address
How do I initialize an optional nested struct in Go?
Use a pointer field and assign a pointer:
Proxy: &ProxyConfig{Address: "addr", Port: "80"}
Check that the field is not nil before reading it.
Can a nested struct have zero values?
Yes. If you do not initialize string fields, they are "". Integer fields become 0, booleans become false, and nested value structs contain the zero values of their fields.
Can I use positional fields instead of field names?
Yes, but keyed fields are safer and clearer:
ProxyConfig{"addr", "80"}
This depends on declaration order, so ProxyConfig{Address: "addr", Port: "80"} is usually preferred.
Mini Project
Description
Build a small application configuration value with nested server and proxy settings. This mirrors how command-line tools and web services organize related configuration while keeping field access clear.
Goal
Create and print a configuration that contains a named nested ProxyConfig struct.
Requirements
Define a ProxyConfig type with Address and Port fields.
Define an AppConfig type with Name and Proxy fields.
Initialize both the outer and nested structs using keyed fields.
Print the application name and complete proxy endpoint.
Use a named type for the nested proxy settings.
Keep learning
Related questions
Are Go Maps Passed by Value or Reference?
Learn Go map parameter and return semantics: maps are passed by value, while copies share underlying data. Know when map pointers are useful.
Authentication for Go REST APIs: Sessions, Tokens, and Middleware
Learn practical authentication patterns for Go REST APIs, including password hashing, server sessions, bearer tokens, middleware, and security rules.
Automatic Build Versioning in Go: Embed Incrementing Build Numbers
Learn how to add automatic build versioning in Go using linker flags, build metadata, CI counters, and Git-based version values.