Elixir Updating Structs
The update syntax %{old | field: value} builds a new struct or map with one field changed. The original value is left untouched and the result is a fresh copy.
Update one field of a struct
The bar syntax takes a struct on the left. It returns a new struct with the age replaced.
defmodule Person do
defstruct name: "Ana", age: 31
end
person = struct(Person)
older = %{person | age: 32}
IO.inspect(older)The original struct stays unchanged
The update builds a separate struct. Printing both shows the first age is still 31.
defmodule Person do
defstruct name: "Ana", age: 31
end
person = struct(Person)
older = %{person | age: 32}
IO.inspect(person)
IO.inspect(older)The same syntax updates a plain map
A plain map uses the same bar syntax. No struct is involved in this update.
person = %{name: "Ana", age: 31}
updated = %{person | age: 32}
IO.inspect(updated)
IO.inspect(person)Example
defmodule Person do
defstruct name: "Ana", age: 31
end
person = struct(Person)
renamed = %{person | name: "Bo", age: 25}
scores = %{ana: 90, bo: 85}
raised = %{scores | ana: 95}
IO.inspect(person)
IO.inspect(renamed)
IO.inspect(raised)Key points
- Update syntax: %{old | age: 32} returns a new value with the named field replaced.
- Existing keys only: The field named after the bar must already exist in the struct or map.
- Original unchanged: The value before the bar keeps its old fields after the update.
- Shared syntax: Structs and plain maps use the exact same update syntax.
- One or more fields: Several fields can be replaced in one update, separated by commas.
In this example, the struct update replaces two fields at once and leaves the original struct at its defaults. The map update then uses the same syntax to raise one score in a plain map.
Note
This works because a struct is a map, so map update syntax applies to it directly.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
After older = %{person | age: 32}, what is person.age when person started at age 31?