Elixir Language
Polimorfismo in elisir
Ricerca…
introduzione
Il polimorfismo è la fornitura di una singola interfaccia per entità di diversi tipi. Fondamentalmente, consente a tipi di dati diversi di rispondere alla stessa funzione. Quindi, la stessa funzione modella per diversi tipi di dati per ottenere lo stesso comportamento. Il linguaggio elisir ha protocols
per implementare il polimorfismo in modo pulito.
Osservazioni
Se si desidera coprire tutti i tipi di dati, è possibile definire un'implementazione per Any
tipo di dati. Infine, se hai tempo, controlla il codice sorgente di Enum e String.Char , che sono buoni esempi di polimorfismo nel nucleo di elisir.
Polimorfismo con protocolli
Implementiamo un protocollo di base che converte le temperature Kelvin e Fahrenheit in gradi 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
Ora, abbiamo implementato i nostri convertitori per i tipi Kelvin e Fahrenheit. Facciamo alcune conversioni:
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"}
Proviamo a convertire qualsiasi altro tipo di dati che non ha implementazione per la funzione 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