Recherche…


Introduction

Le polymorphisme consiste à fournir une interface unique à des entités de types différents. Fondamentalement, il permet à différents types de données de répondre à la même fonction. Donc, les mêmes fonctions de forme pour différents types de données pour accomplir le même comportement. Le langage Elixir a des protocols pour implémenter le polymorphisme de manière propre.

Remarques

Si vous souhaitez couvrir tous les types de données, vous pouvez définir une implémentation pour Any type de données. Enfin, si vous avez le temps, vérifiez le code source de Enum et String.Char , qui sont de bons exemples de polymorphisme dans le noyau Elixir.

Polymorphisme Avec Protocoles

Implémentons un protocole de base qui convertit les températures Kelvin et Fahrenheit en 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

Maintenant, nous avons implémenté nos convertisseurs pour les types Kelvin et Fahrenheit. Faisons quelques conversions:

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"}

Essayons de convertir tout autre type de données sans implémentation pour la fonction 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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow