jonnifyelixir
F3 · The Elixir Language / F3.05 · structs

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

QUERY fetch :role MAP · %{role: :student}hash :role → one bucket any key, checked at run time VALUE :student

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

LEARNER DATA · AS SELECTED %{email: "ada@portal.dev", role: :student} PROPERTIES THAT HOLD order is kept duplicate keys allowed key set is fixed at compile time

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.

F3.05.1
Defining a struct
defstruct over Portal.Accounts.User, the %User{} literal, and the __struct__ key that makes a struct a map.
F3.05.2
Enforcing keys & defaults
@enforce_keys for required fields and default values in defstruct — what fills in, and what fails.
F3.05.3
Matching on a struct's type
The %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.