Suche…


Einführung

Polymorphismus ist die Bereitstellung einer einzigen Schnittstelle für Entitäten verschiedener Typen. Grundsätzlich können verschiedene Datentypen auf dieselbe Funktion reagieren. Dieselbe Funktion ist also für verschiedene Datentypen geeignet, um dasselbe Verhalten zu erreichen. Elixiersprache verfügt über protocols , um Polymorphismus auf saubere Weise zu implementieren.

Bemerkungen

Wenn Sie alle Datentypen abdecken möchten, können Sie eine Implementierung für den Datentyp Any definieren. Wenn Sie Zeit haben, überprüfen Sie den Quellcode von Enum und String.Char. Dies sind gute Beispiele für Polymorphismen in Core-Elixir.

Polymorphismus mit Protokollen

Implementieren wir ein Basisprotokoll, das die Temperaturen in Kelvin und Fahrenheit in Celsius umwandelt.

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

Jetzt haben wir unsere Konverter für die Typen Kelvin und Fahrenheit implementiert. Lassen Sie uns einige Konvertierungen vornehmen:

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

Versuchen wir, einen anderen Datentyp zu konvertieren, für den die to_celsius Funktion nicht implementiert ist:

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow