F3 · Data & shape · module 5
Shaping data with structs
The collections walked in F3.04 were maps — loose bags of keys and values. That works until a value needs a guaranteed shape: a learner is always an id, an email, and a role, never something else. Elixir gives three containers for key-and-value data — the map, the keyword list, and the struct — and the skill is knowing which one a situation calls for.
The portal's Portal.Accounts.User is the running example. The same
learner data fits all three shapes; this module shows what each one guarantees and gives up, then takes the
struct apart over three deep dives.
Reaching one field
map · hashed access
Any key, resolved at run time · about O(log n).
Three shapes, one record
A map takes any keys and lets you add or drop them at runtime. A keyword list is an ordered list of
{atom, value} pairs whose keys may repeat — the shape options are passed in.
A struct fixes its key set at compile time and stamps the value with its module. Choose a shape and watch the
same learner data take its form, and which properties hold.
The same record, three shapes · select one
No shape is best everywhere: a map for open-ended data, a keyword list for ordered options, a struct when a value must always carry the same fields. A struct is the only one of the three that a compiler can check.
Three deep dives
Three pages take the struct apart in order: defining one over a portal entity, enforcing its keys and filling defaults, then matching on the type it carries.
defstruct over Portal.Accounts.User, the %User{} literal, and the __struct__ key that makes a struct a map.@enforce_keys for required fields and default values in defstruct — what fills in, and what fails.%User{} pattern, dispatch by struct tag across function clauses, and the is_struct/2 guard.F2.07 · product types
A product type holds several fields together — a name and a fixed shape, all present at once.
F3 · the struct
A struct is a product type with a name: a fixed set of fields over a map, tagged with its module.
Start with defining a struct, then enforcing keys and defaults, then matching on its type. Next module: F3.06 — Protocols & behaviours, where the struct tag becomes the basis for polymorphism.
References
Primary sources for this lesson, and where it connects in the course.
Sources
- Keywords and maps — Elixir documentation — choosing a data shape.
- Structs — Elixir documentation — named, typed maps.
Map— Elixir documentation — the map module.