Elixir Language
Polymorphisme chez Elixir
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