a common mistake when using Type Conversion Vs Assertion
Fast recall
Quick revision
Core answer
Practical understanding of Type Conversion Vs Assertion.
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
The one legal case — identical structure:
type A struct { X int; Y string }
type B struct { X int; Y string }
a := A{1, "hi"}
b := B(a) // works — same names, types, order, tagsThe compiler verifies: field names identical, types identical, order identical, struct tags identical. Different names, extra fields, different order, different tags — compile error. There's no partial matching, no 'convert the common fields.'
The mechanism behind it: two structs with identical underlying types are really the same memory layout wearing two names — conversion is a reinterpretation (the value copies; nothing is remapped). It exists for the named-type-from-same-shape case — wrapping a type in a domain name without losing conversion access.
Everything else — the real struct-to-struct needs (DTO → domain model, adding/removing fields, different names) — is manual mapping:
func toDomain(d OrderDTO) Order {
return Order{ID: d.ID, Total: d.TotalCents / 100}
}The mapping function is Go's answer to what other languages solve with inheritance hierarchies or serializers. It's verbose but explicit — every field's journey is visible, nothing transforms silently.
a common mistake when using Type Conversion Vs Assertion
Direct Answer
No direct struct-to-struct conversion in general — only when the structs have IDENTICAL field names, types, order, and tags (the 'identical underlying type' rule). Otherwise: map fields manually (or via a conversion library).
Deep Dive & Architecture
Why the rule is structure-exact: conversion semantics are 'the bits of x are now interpretable as T.' For that to be sound, the memory layouts must match exactly — and Go's struct layout is (names, order, types, tags) — hence the identity requirement. A conversion that remapped fields would be a copy-constructor, not a conversion; Go puts constructors (even implicit ones) nowhere in the language, so conversion stays what it is: reinterpretation.
The tag-identity subtlety (the deep edge): tags participate in type identity — struct{X int "a"} and struct{X int "b"} are NOT convertible. This surprises people because tags feel like metadata, but the rule protects the round-trip (encoding/json keys off tags; a tag-changing conversion would silently change serialization — the identity rule keeps conversion from being a hidden transform).
The ecosystem's answer to the verbosity: struct-mapping libraries (copier, mapstructure) use reflection to copy fields by name/type — convenient at the cost of runtime reflection and silent skips (fields present in one and not the other just don't copy). The stdlib-philosophy alternative: write the mapping function — it's the only approach where the compiler verifies every field, refactors safely (adding a field to the source forces the mapping to choose), and the data flow is greppable. Interviews reward naming the trade: reflection-mappers trade explicitness for brevity, and the trade bites when a renamed field silently stops copying.
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 Type Conversion Vs Assertion, and when would you use it?
- When would you use Type Conversion Vs Assertion in a real project?
- How would you compare Type Conversion Vs Assertion with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.