Что означает `@type t::% __ MODULE __ {}` означает в Elixir

В пакетах std Elixir есть много строк, например

@type t :: %__MODULE__{}

Я знаю, что аннотация @type используется для псевдонимов коротких обозначений типа в аннотациях @spec, но эта строка используется в таких модулях, как uri.ex, который вообще не имеет аннотаций @spec.

Какова цель этой аннотации?

Ответ 1

Прежде всего, типы, указанные в директиве @type, по умолчанию являются общедоступными (в отличие от типов, определенных с помощью @typep). Это означает, что даже если в модуле нет спецификаций, определение типа позволяет другим разработчикам использовать этот тип при написании своих функций:

@doc "Computes the length of a URI."
@spec foo(URI.t) :: non_neg_integer
def foo(uri), do: # ...

__MODULE__ - специальная форма, которая расширяется до текущего имени модуля как атома (см. docs для него), так что:

defmodule MyModule do
  @type t :: %__MODULE__{}
end

будет определять тип MyModule.t. Наиболее распространенное использование типа t - для представления структур и протоколов (например, Enum.t). Эта схема чрезвычайно распространена:

defmodule User do
  defstruct [:name, :email]
  @type t :: %__MODULE__{name: String.t, email: String.t}
end