Structs in Go
Structs are one of the most important data structures in Go. They allow you to group related data into a single unit. Structs are widely used to represent real-world entities such as users, orders, products, employees, and configurations.
In real applications, structs form the foundation of APIs, databases, services, and business logic.
Why Structs Are Needed
So far, you have worked with individual variables. But real programs deal with related data.
- User details (name, email, age)
- Bank account (account number, balance, status)
- Product information (id, price, quantity)
Structs allow you to model such data cleanly and logically.
Defining a Struct
A struct is defined using the type keyword followed by the
struct keyword.
type User struct {
ID int
Name string
Age int
Email string
}
This defines a new data type called User
that groups multiple fields together.
Creating Struct Values
Once defined, you can create struct values using different methods.
Method 1: Field-by-field Initialization
user := User{
ID: 101,
Name: "Arjun",
Age: 28,
Email: "arjun@example.com",
}
This approach is clear and preferred in production code.
Method 2: Positional Initialization
user := User{101, "Arjun", 28, "arjun@example.com"}
This works but is error-prone and not recommended for large structs.
Accessing Struct Fields
You access struct fields using the dot (.) operator.
fmt.Println(user.Name)
fmt.Println(user.Age)
Each field behaves like a normal variable.
Modifying Struct Fields
Struct fields can be updated directly.
user.Age = 29
user.Email = "arjun.new@example.com"
This updates only the specific fields without affecting the rest.
Structs with Pointers
In real applications, structs are often passed as pointers to avoid copying large amounts of data.
func updateEmail(u *User, newEmail string) {
u.Email = newEmail
}
func main() {
user := User{ID: 102, Name: "Meera", Age: 31, Email: "meera@example.com"}
updateEmail(&user, "meera.work@example.com")
fmt.Println(user.Email)
}
Go automatically dereferences struct pointers, making pointer-based code clean and readable.
Real-World Example: Bank Account
Structs are perfect for modeling financial data.
type Account struct {
AccountNumber string
Balance float64
Active bool
}
func deposit(a *Account, amount float64) {
a.Balance += amount
}
func main() {
acc := Account{
AccountNumber: "ACC-9001",
Balance: 2500.50,
Active: true,
}
deposit(&acc, 749.50)
fmt.Println("Balance:", acc.Balance)
}
This pattern is widely used in banking and payment systems.
Nested Structs
Structs can contain other structs as fields.
type Address struct {
City string
State string
}
type Customer struct {
Name string
Address Address
}
This helps model complex real-world data hierarchies.
Zero Values in Structs
When a struct is declared without initialization, each field gets its zero value.
- int → 0
- string → ""
- bool → false
Best Practices
- Use structs to model real-world entities
- Prefer named field initialization
- Pass structs by pointer when large
- Keep structs focused and meaningful
What’s Next?
In the next lesson, you will learn about Methods in Go, which allow functions to be attached directly to structs.