Elixir Language
Polymorfism i Elixir
Sök…
Introduktion
Polymorfism är tillhandahållandet av ett enda gränssnitt till enheter av olika typer. I grunden tillåter det att olika datatyper svarar på samma funktion. Så samma funktion formas för olika datatyper för att uppnå samma beteende. Elixir-språk har protocols att implementera polymorfism på ett rent sätt.
Anmärkningar
Om du vill täcka alla datatyper kan du definiera en implementering för Any datatyp. Slutligen, om du har tid, kolla källkoden för Enum och String.Char , som är bra exempel på polymorfism i kärn Elixir.
Polymorfism med protokoll
Låt oss genomföra ett grundläggande protokoll som konverterar Kelvin- och Fahrenheit-temperaturer till Celsius.
defmodule Kelvin do
defstruct name: "Kelvin", symbol: "K", degree: 0
end
defmodule Fahrenheit do
defstruct name: "Fahrenheit", symbol: "°F", degree: 0
end
defmodule Celsius do
defstruct name: "Celsius", symbol: "°C", degree: 0
end
defprotocol Temperature do
@doc """
Convert Kelvin and Fahrenheit to Celsius degree
"""
def to_celsius(degree)
end
defimpl Temperature, for: Kelvin do
@doc """
Deduct 273.15
"""
def to_celsius(kelvin) do
celsius_degree = kelvin.degree - 273.15
%Celsius{degree: celsius_degree}
end
end
defimpl Temperature, for: Fahrenheit do
@doc """
Deduct 32, then multiply by 5, then divide by 9
"""
def to_celsius(fahrenheit) do
celsius_degree = (fahrenheit.degree - 32) * 5 / 9
%Celsius{degree: celsius_degree}
end
end
Nu implementerade vi våra omvandlare för Kelvin- och Fahrenheit-typerna. Låt oss göra några omvandlingar:
iex> fahrenheit = %Fahrenheit{degree: 45}
%Fahrenheit{degree: 45, name: "Fahrenheit", symbol: "°F"}
iex> celsius = Temperature.to_celsius(fahrenheit)
%Celsius{degree: 7.22, name: "Celsius", symbol: "°C"}
iex> kelvin = %Kelvin{degree: 300}
%Kelvin{degree: 300, name: "Kelvin", symbol: "K"}
iex> celsius = Temperature.to_celsius(kelvin)
%Celsius{degree: 26.85, name: "Celsius", symbol: "°C"}
Låt oss försöka konvertera någon annan datatyp som inte har någon implementering för to_celsius funktionen:
iex> Temperature.to_celsius(%{degree: 12})
** (Protocol.UndefinedError) protocol Temperature not implemented for %{degree: 12}
iex:11: Temperature.impl_for!/1
iex:15: Temperature.to_celsius/1