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