Structs

12.1 Defining

A struct is a map with a __struct__ key. %User{} with a missing enforced key raises at compile time.

defmodule User do
  @enforce_keys [:email]
  defstruct [:email, name: "Anonymous", age: 0, roles: []]
end

u = %User{email: "a@b.com"}
u.name                    # "Anonymous"
u = %{u | age: 31}        # update
%User{name: name} = u     # pattern match
is_struct(u, User)        # true

12.2 Structs don't implement Access or Enumerable by default

u[:name]          # ** (UndefinedFunctionError) — use u.name or Map.get(u, :name)
Enum.map(u, ...)  # Protocol.UndefinedError

12.3 Functions with structs

__MODULE__ refers to the current module name.

defmodule User do
  defstruct [:email, :name, active: true]

  def new(email, name), do: %__MODULE__{email: email, name: name}
  def deactivate(%__MODULE__{} = user), do: %{user | active: false}
  def display(%__MODULE__{name: name, email: email}), do: "#{name} <#{email}>"
end

12.4 Deriving protocol implementations

defmodule Secret do
  @derive {Inspect, except: [:password]}
  @derive {Jason.Encoder, only: [:username]}
  defstruct [:username, :password]
end