Zoeken…


Invoering

Polymorfisme is het verschaffen van een enkele interface voor entiteiten van verschillende typen. Kort gezegd kunnen verschillende gegevenstypen op dezelfde functie reageren. Dus, dezelfde functie vormt voor verschillende gegevenstypen om hetzelfde gedrag te bereiken. De taal van het Elixer heeft protocols om polymorfisme op een schone manier te implementeren.

Opmerkingen

Als u alle gegevenstypen wilt dekken, kunt u een implementatie definiëren voor Any gegevenstype. Ten slotte, als je tijd hebt, controleer dan de broncode van Enum en String.Char , die goede voorbeelden zijn van polymorfisme in kernelixir .

Polymorfisme met protocollen

Laten we een basisprotocol implementeren dat Kelvin- en Fahrenheit-temperaturen omzet in 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 hebben we onze converters geïmplementeerd voor de types Kelvin en Fahrenheit. Laten we wat conversies maken:

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"}

Laten we proberen een ander gegevenstype te converteren dat geen implementatie heeft voor de functie 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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow