Elixir - Typespecs

Elixir é uma linguagem de tipagem dinâmica, portanto, todos os tipos no Elixir são inferidos pelo tempo de execução. No entanto, Elixir vem com typespecs, que são uma notação usada paradeclaring custom data types and declaring typed function signatures (specifications).

Especificações de função (especificações)

Por padrão, Elixir fornece alguns tipos básicos, como inteiro ou pid, e também tipos complexos: por exemplo, o roundfunção, que arredonda um float para seu inteiro mais próximo, recebe um número como um argumento (um inteiro ou um float) e retorna um inteiro. Na documentação relacionada , a assinatura digitada por rodada é escrita como -

round(number) :: integer

A descrição acima implica que a função à esquerda toma como argumento o que está especificado entre parênteses e retorna o que está à direita de ::, ou seja, Inteiro. As especificações da função são escritas com o@spec, colocada logo antes da definição da função. A função round pode ser escrita como -

@spec round(number) :: integer
def round(number), do: # Function implementation
...

Tipos de especificações também suportam tipos complexos, por exemplo, se você deseja retornar uma lista de inteiros, então você pode usar [Integer]

Tipos personalizados

Embora Elixir forneça muitos tipos embutidos úteis, é conveniente definir tipos personalizados quando apropriado. Isso pode ser feito ao definir módulos por meio da diretiva @type. Vamos considerar um exemplo para entender o mesmo -

defmodule FunnyCalculator do
   @type number_with_joke :: {number, String.t}

   @spec add(number, number) :: number_with_joke
   def add(x, y), do: {x + y, "You need a calculator to do that?"}

   @spec multiply(number, number) :: number_with_joke
   def multiply(x, y), do: {x * y, "It is like addition on steroids."}
end

{result, comment} = FunnyCalculator.add(10, 20)
IO.puts(result)
IO.puts(comment)

Quando o programa acima é executado, ele produz o seguinte resultado -

30
You need a calculator to do that?

NOTE - Os tipos personalizados definidos por meio de @type são exportados e estão disponíveis fora do módulo em que foram definidos. Se quiser manter um tipo personalizado privado, você pode usar @typep diretiva em vez de @type.