Elixir - мова з динамічною типізацією, тобто вона не виконує перевірок типів під час компіляції. Утім, специфікації типів можуть бути корисними, бо вони:
Специфікацію типу можна додати до функції за допомогою атрибута модуля @spec одразу перед визначенням функції.
@spec longer_than?(String.t(), non_neg_integer()) :: boolean()
def longer_than?(string, length), do: String.length(string) > length
Вирази, дозволені у специфікації типу:
Базові типи, наприклад:
boolean()integer(), non_neg_integer(), pos_integer(), float()
list()map()any()Обʼєднання типів:
integer() | list(integer())
Параметризовані типи:
list(integer()) - список цілих чисел%{age: integer()} - мапа з цілим значенням за ключем :age
Віддалені типи (визначені в якомусь модулі), наприклад:
Літерали, наприклад:
%{} - порожня мапа[] - порожній список (але [any()] - це непорожній список):ok - літерал атомаВбудовані спеціалізовані типи, наприклад:
char() - ціле число з діапазону 0..0x10FFFF
charlist() - список символівkeyword() - список двоелементних кортежів, де перший елемент - атомВласні типи
Повний список усіх типів можна знайти в розділі «Typespecs» в офіційній документації.
Аргументи у специфікації типу також можна назвати, що корисно, коли треба розрізнити кілька аргументів одного типу.
@spec to_hex({hue :: integer, saturation :: integer, lightness :: integer}) :: String.t()
Власні типи можна визначити за допомогою одного з трьох атрибутів модуля:
@type - визначає публічний тип@typep - визначає приватний тип@opaque - визначає публічний тип, структура якого приватна@type color :: {hue :: integer, saturation :: integer, lightness :: integer}
@spec to_hex(color()) :: String.t()
String.t() проти binary() проти string()
String.t() - правильний тип для рядків Elixir, які є бінарними даними в кодуванні UTF-8. Технічно String.t() визначено як binary(), і для інструментів аналізу ці два типи еквівалентні, але String.t() краще передає намір, коли треба задокументувати функції, що працюють із рядками Elixir.
З іншого боку, string() - це інший тип. Це рядок Erlang, який в Elixir називають списком символів. Типу string() слід уникати у специфікаціях типів, а натомість використовувати charlist().
Dialyzer - інструмент статичного аналізу, який може виявляти проблеми, як-от помилки типів у коді Erlang та Elixir. Найпростіший спосіб використовувати Dialyzer у проєкті Elixir - це Dialyxir.