Interfaces in Elixir
In Elixir, we don’t have interfaces in the same way as Go, but we can achieve similar behavior using protocols. Here’s how we can implement the geometry example:
defprotocol Geometry do
def area(shape)
def perim(shape)
end
defmodule Rect do
defstruct width: 0, height: 0
defimpl Geometry, for: Rect do
def area(rect), do: rect.width * rect.height
def perim(rect), do: 2 * rect.width + 2 * rect.height
end
end
defmodule Circle do
defstruct radius: 0
defimpl Geometry, for: Circle do
def area(circle), do: :math.pi() * circle.radius * circle.radius
def perim(circle), do: 2 * :math.pi() * circle.radius
end
end
defmodule Shapes do
def measure(shape) do
IO.inspect(shape)
IO.puts(Geometry.area(shape))
IO.puts(Geometry.perim(shape))
end
end
# In the main function
rect = %Rect{width: 3, height: 4}
circle = %Circle{radius: 5}
Shapes.measure(rect)
Shapes.measure(circle)In this Elixir code:
We define a
Geometryprotocol withareaandperimfunctions.We create
RectandCirclestructs and implement theGeometryprotocol for each.The
measurefunction in theShapesmodule takes any shape that implements theGeometryprotocol.In the main part of the script, we create instances of
RectandCircleand pass them to themeasurefunction.
To run this program, save it in a file (e.g., shapes.exs) and use the elixir command:
$ elixir shapes.exs
%Rect{width: 3, height: 4}
12
14
%Circle{radius: 5}
78.53981633974483
31.41592653589793Elixir’s protocols provide a way to achieve polymorphism, similar to interfaces in other languages. They allow us to define a set of functions that can be implemented by different types, enabling us to write more generic and reusable code.