Struct usage patterns in Go - Time & Space Complexity
When using structs in Go, it is important to understand how operations on them grow as data size increases.
We want to know how the time to access or modify struct data changes when we have many structs or nested structs.
Analyze the time complexity of the following code snippet.
package main
import "fmt"
type Person struct {
Name string
Age int
}
func printNames(people []Person) {
for _, p := range people {
fmt.Println(p.Name)
}
}
func main() {
people := []Person{{"Alice", 30}, {"Bob", 25}, {"Carol", 27}}
printNames(people)
}
This code defines a struct Person and prints the Name field for each person in a slice.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through the slice of Person structs.
- How many times: Once for each element in the slice (n times).
As the number of Person structs increases, the time to print all names grows proportionally.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 print operations |
| 100 | 100 print operations |
| 1000 | 1000 print operations |
Pattern observation: The time grows directly with the number of structs; doubling the structs doubles the work.
Time Complexity: O(n)
This means the time to process all structs grows linearly with how many structs there are.
[X] Wrong: "Accessing a field inside a struct takes extra time for each field."
[OK] Correct: Accessing a field in a struct is a direct operation and does not add extra loops or repeated work; the main time cost comes from how many structs you process.
Understanding how operations on structs scale helps you write efficient code and explain your reasoning clearly in interviews.
"What if we changed the slice of structs to a nested struct with slices inside? How would the time complexity change?"
Practice
struct in Go?Solution
Step 1: Understand the role of structs
Structs are used to group related data together in one unit with named fields.Step 2: Compare with other options
Arithmetic, loops, and error handling are not the main purposes of structs.Final Answer:
To group related data with named fields -> Option AQuick Check:
Structs = Group related data [OK]
- Thinking structs are for control flow
- Confusing structs with functions
- Assuming structs handle errors
Person with fields Name (string) and Age (int)?Solution
Step 1: Recall Go struct declaration syntax
In Go, a struct type is declared with the keywordtype, followed by the name, thenstructand fields inside braces.Step 2: Check each option
type Person struct { Name string; Age int } matches the correct syntax. struct Person { Name string; Age int } missestype. Person := struct { Name string; Age int } uses := which is for variables, not type declaration. var Person struct Name string; Age int is invalid syntax.Final Answer:
type Person struct { Name string; Age int } -> Option DQuick Check:
Struct declaration uses 'type Name struct { fields }' [OK]
- Omitting 'type' keyword
- Using := for type declaration
- Incorrect field syntax
type Point struct {
X int
Y int
}
func main() {
p := Point{X: 3, Y: 4}
p.X = 10
fmt.Println(p.X, p.Y)
}Solution
Step 1: Understand struct initialization and modification
The struct Point is initialized with X=3 and Y=4. Then p.X is changed to 10.Step 2: Determine printed values
After modification, p.X is 10 and p.Y remains 4. So printing p.X and p.Y outputs '10 4'.Final Answer:
10 4 -> Option AQuick Check:
Modified field prints updated value [OK]
- Assuming original values stay after assignment
- Confusing field names
- Forgetting to import fmt (not shown here)
type Car struct {
Brand string
Year int
}
func main() {
c := Car{Brand: "Toyota", Year: "2020"}
fmt.Println(c)
}Solution
Step 1: Check field types in struct literal
The struct Car has Year as int, but the code assigns "2020" (a string) to Year.Step 2: Verify other options
Semicolons are optional in Go. Struct name capitalization is fine. fmt.Println can print structs.Final Answer:
Year field assigned a string instead of int -> Option BQuick Check:
Field types must match assigned values [OK]
- Assigning wrong data types to fields
- Thinking semicolons are mandatory
- Assuming fmt.Println can't print structs
Employee with fields Name (string), Salary (int), and Active (bool), which code snippet correctly creates a slice of active employees with salary over 50000 from a given slice emps?Solution
Step 1: Understand filtering conditions
We want employees who are active AND have salary greater than 50000.Step 2: Analyze each option's condition
var filtered []Employee for _, e := range emps { if e.Active && e.Salary > 50000 { filtered = append(filtered, e) } } uses correct AND condition. filtered := []Employee{} for i := 0; i < len(emps); i++ { if emps[i].Salary > 50000 { filtered = append(filtered, emps[i]) } } misses Active check. filtered := make([]Employee, 0) for _, e := range emps { if e.Active || e.Salary > 50000 { filtered = append(filtered, e) } } uses OR instead of AND. filtered := []Employee{} for _, e := range emps { if e.Active && e.Salary < 50000 { filtered = append(filtered, e) } } uses salary less than 50000, which is wrong.Final Answer:
var filtered []Employee for _, e := range emps { if e.Active && e.Salary > 50000 { filtered = append(filtered, e) } } -> Option CQuick Check:
Use AND (&&) for combined conditions [OK]
- Using || instead of && for filtering
- Ignoring one of the filter conditions
- Filtering with wrong comparison operators
Ready to prove it?
Pass the test and this pattern moves unknown
