a common mistake when using Struct Definition
Fast recall
Quick revision
Core answer
Practical understanding of Struct Definition.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
== on structs works exactly when it can: all fields comparable → element-wise comparison; any non-comparable field (slice, map, function — note: channels and interfaces ARE comparable) → compile error:
User{Name:"a", Age:1} == User{Name:"a", Age:1} // true — all fields equal, executed
User{Name:"a", Age:1} == User{Name:"b", Age:1} // false — any field differs
type Doc struct { Tags []string }
// Doc{...} == Doc{...} // compile error: Doc is not comparableThe comparison is field-by-field in declaration order — the same == semantics each field type has. Two consequences: it's shallow (pointer fields compare by pointer, not pointee), and it's all-or-nothing (the compiler refuses the WHOLE struct if ANY field can't compare — no partial equality).
For structs that can't ==: reflect.DeepEqual (runtime, panics on some cycles, slow — the test-time tool) or slices/maps-based comparisons or a hand-written Equal method (production code — explicit, fast, version-able semantics). The honest interview progression: == when the compiler allows it; Equal() method when equality is a domain concept with its own definition (case-insensitive names? nil-vs-empty normalization?); DeepEqual in tests only.
The copy semantics pair: assignment (u2 := u) copies all fields — shallowly (reference fields share their pointees) — so == and copy are consistent: equal structs stay equal after independent assignment until a mutable shared field changes under one of them.
a common mistake when using Struct Definition
Direct Answer
Structs are comparable with == when ALL their fields are comparable — field-by-field, in order. Any slice/map/function/chan... channels ARE comparable... any slice, map, or function field makes == a compile error.
Deep Dive & Architecture
Why the strictness? Go's design: == must be cheap, well-defined, and hashable (usable as map keys) — so any type with == gets the full suite. A slice can't == because 'same contents or same identity?' has no right answer cheaply; a struct holding one inherits the ambiguity — the compiler stops it at the boundary instead of picking a semantics.
The map-key corollary, worth stating because it's a standard follow-up question: comparable structs are valid map keys. map[User]int — Go hashes all fields. The rules propagate: change a field to []string and the map breaks too (compile error, not a runtime surprise).
The shallow comparison detail: type P struct{ U *User; N int }; P{u1, 1} == P{u2, 1} compares the POINTERS u1 == u2, not *u1 == *u2. Two structs with identical pointed-to data are unequal if they hold different pointers — the same identity-vs-equality distinction Go made for channels and interfaces, applied through struct fields. When that's wrong for your domain, the Equal() method is where you define it.
reflect.DeepEqual exists because tests need structural equality over graphs (documents with slices containing slices) — but it answers a different question than == (deep structural equivalence, nil-vs-empty distinct in some cases) and its performance (reflection over every field) and edge semantics (cycles panic) keep it out of production paths. The test/production line is the practical answer interviewers want: == for the cheap hashable types, Equal() for domain semantics, DeepEqual for test fixtures.
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Struct Definition, and when would you use it?
- When would you use Struct Definition in a real project?
- How would you compare Struct Definition with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.