Elixir Language
Polymorphismus in Elixier
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