Sponsored by AppSignal
Would you like to see your link here? Contact us
Notesclub

Structs

3_structs.livemd

Structs

import IEx.Helpers

Defining Structs

defmodule User do
  defstruct name: "Jill", age: 25

  def new do
    %User{name: "Bruce", age: 21}
  end
end
{:module, User, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:new, 0}}
defmodule Point do
  defstruct [:x, :y]
end
{:module, Point, <<70, 79, 82, 49, 0, 0, 8, ...>>, %Point{x: nil, y: nil}}
Point.__struct__()
%Point{x: nil, y: nil}
User.new()
%User{name: "Bruce", age: 21}
u = %User{age: 26}
%User{name: "Jill", age: 26}

The struct key and function

# exports from erlang
exports(User)
__struct__/0     __struct__/1     new/0            
# __ => dunder struct => double underscore struct
User.__struct__(%{age: 30})
%User{name: "Jill", age: 30}
# __ => dunder struct => double underscore struct
User.__struct__(age: 30)
%User{name: "Jill", age: 30}
Map.keys(u)
[:name, :__struct__, :age]
u.__struct__
User

Protocols

i(%{})
Term
  %{}
Data type
  Map
Reference modules
  Map
Implemented protocols
  Collectable, Enumerable, IEx.Info, Inspect
i(%Point{})
Term
  %Point{x: nil, y: nil}
Data type
  Point
Description
  This is a struct. Structs are maps with a __struct__ key.
Reference modules
  Point, Map
Implemented protocols
  IEx.Info, Inspect
is_map(%Point{})
true
is_struct(%Point{})
true
Enum.count(%{one: 1})
1
Enum.count(Point.__struct__())
map = %{one: 1, two: 2}
map[:two]
2
map.one
1
{map.one, map[:two]}
{1, 2}
user = User.new()
user.name
"Bruce"
user[:age]

Common structs in Elixir

IEx.Helpers.i(Date.utc_today())
Term
  ~D[2024-01-03]
Data type
  Date
Description
  This is a struct representing a date. It is commonly
  represented using the `~D` sigil syntax, that is
  defined in the `Kernel.sigil_D/2` macro.
Raw representation
  %Date{year: 2024, month: 1, day: 3, calendar: Calendar.ISO}
Reference modules
  Date, Calendar, Map
Implemented protocols
  IEx.Info, Inspect, String.Chars
Date.utc_today() |> Map.keys()
[:calendar, :month, :__struct__, :day, :year]
DateTime.utc_now() |> Map.keys()
[:microsecond, :second, :calendar, :month, :__struct__, :day, :year, :minute, :hour, :time_zone,
 :zone_abbr, :utc_offset, :std_offset]