People searching for golang array of structs, golang struct array, go array of structs, or golang list of structs usually want a collection of the same struct type. In Go that is either a fixed-length array [n]Person or, much more often, a slice []Person whose length can change. This guide shows golang initialize array of structs with literals, make for preallocated slices (golang make array style), iteration with range, and field updates—including when a slice of pointers []*Student is clearer. For the struct type itself, see structs in Go; for growing collections, see append to slice; for passing collections to functions, see pass array or slice to a function; for finding a row by ID or SKU, see search an element in a slice; for pointers, see Go pointers.
Tested with Go 1.24 on Linux.
Fixed array [n]Struct vs slice []Struct
[3]Student: length 3 is part of the type; copying the value copies all three elements.[]Student: header with pointer, length, and capacity;appendcan grow it (see append).
For most “golang array of objects” style lists, use a slice.
golang initialize array of structs (composite literals)
Slice literal (common “golang create array of structs” pattern):
package main
import "fmt"
type Student struct {
Name string
Grade int
}
func main() {
students := []Student{
{Name: "Alice", Grade: 90},
{Name: "Bob", Grade: 85},
}
fmt.Println(students[0].Name, len(students))
}You should see Alice 2.
Fixed-size array literal:
package main
import "fmt"
type Student struct {
Name string
Grade int
}
func main() {
team := [2]Student{
{Name: "Ada", Grade: 99},
{Name: "Lin", Grade: 94},
}
fmt.Println(team[1].Name)
}You should see Lin.
golang make array of structs (make + assign)
make applies to slices (and maps/channels), not to array types [n]T:
package main
import "fmt"
type Student struct {
Name string
Grade int
}
func main() {
s := make([]Student, 2)
s[0] = Student{Name: "Mia", Grade: 88}
s[1].Name = "Noor"
s[1].Grade = 91
fmt.Println(s)
}You should see two structs with the grades you set. Use make([]Student, 0, cap) when you plan to append many rows.
Iterate with range (go array of structs)
package main
import "fmt"
type Student struct {
Name string
Grade int
}
func main() {
students := []Student{
{"Alice", 90},
{"Bob", 85},
}
for i, st := range students {
fmt.Println(i, st.Name, st.Grade)
}
}You should see two lines with indices 0 and 1. For loop variants, see for loops in Go.
Updating fields: value slice vs []*Student
With []Student, st := range gives a copy; mutating st does not write back unless you assign by index:
package main
import "fmt"
type Student struct {
Name string
Grade int
}
func main() {
students := []Student{{"Ada", 90}}
students[0].Grade = 95
fmt.Println(students[0].Grade)
}You should see 95.
When helpers take *Student and mutate, a pointer slice avoids index noise:
package main
import "fmt"
type Student struct {
Name string
Grade int
}
func bump(s *Student) { s.Grade++ }
func main() {
students := []*Student{
{Name: "Ada", Grade: 90},
}
bump(students[0])
fmt.Println(students[0].Grade)
}You should see 91.
Summary
Golang array of structs can mean a true array [n]T or, more often, a slice []T acting as a golang list of structs. Use composite literals for golang initialize array of structs, make([]T, len) when you need allocation first (golang make array), and for range to walk rows. Update fields with index assignment on value slices, or use []*Struct when functions take pointers. Prefer slices unless the length is a fixed part of your model.
References
- Go spec — Composite literals
- Effective Go — Arrays
- Effective Go — Slices
Frequently Asked Questions
What is the difference between a golang array of structs and a slice of structs?
An array has type [n]Student with a fixed length in the type; a slice has type []Student with variable length backed by an array. Most APIs use a slice; use an array when the length is a true compile-time constant part of the type.
How do I golang initialize array of structs in one line?
Use a composite literal: students := []Student{{Name: "Alice", Grade: 90}, {Name: "Bob", Grade: 85}} for a slice, or students := [2]Student{{...}, {...}} for a fixed-size array.
How does golang make array of structs work?
Call make on a slice type: s := make([]Student, 3) allocates length and capacity 3 with zeroed structs; use a second loop or index assignment to set fields, or make([]Student, 0, 8) then append.
Is golang list of structs the same as an array?
People often say list when they mean a slice []T; create and grow it with append or preallocate with make then assign by index.
Can I update a struct inside an array or slice?
Yes with index and dot notation: s[i].Name = x for values; for slices of structs you may need s[i].Field = x or a pointer slice []*T if you pass elements to helpers that mutate through pointers.

