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