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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow