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