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


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow