Elixir Language
Polimorfizm w eliksiru
Szukaj…
Wprowadzenie
Polimorfizm jest zapewnianiem jednego interfejsu dla bytów różnego typu. Zasadniczo pozwala różnym typom danych reagować na tę samą funkcję. Tak więc kształty tej samej funkcji dla różnych typów danych pozwalają osiągnąć to samo zachowanie. Język eliksiru ma protocols do implementacji polimorfizmu w czysty sposób.
Uwagi
Jeśli chcesz objąć wszystkie typy danych, możesz zdefiniować implementację dla Any typu danych. Na koniec, jeśli masz czas, sprawdź kod źródłowy Enum i String.Char , które są dobrymi przykładami polimorfizmu w rdzeniu Elixir.
Polimorfizm z protokołami
Zaimplementujmy podstawowy protokół, który konwertuje temperatury Kelvina i Fahrenheita na stopnie Celsjusza.
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
Teraz wdrożyliśmy nasze konwertery dla typów Kelvin i Fahrenheit. Zróbmy kilka konwersji:
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"}
Spróbujmy przekonwertować dowolny inny typ danych, który nie ma implementacji dla funkcji to_celsius :
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