Elixir - 为什么@callback定义中需要类型规范?

Ray*_*y J 5 types module behavior elixir

似乎在定义行为时,您必须在@callback定义中包含类型规范.然后,当您采用该行为时,编译器要求function_name/arity已定义,但如果您不遵循类型规范,则非常高兴.

我的问题是:

  1. 这些观察是否正确?
  2. 如果是的话,为什么@callback一对类型规格与检查function_name/arity定义的实际功能类型?这使得很难理解什么是文档以及什么是核心功能.Elixir的其余部分似乎清楚地将两者分开,保持类型规格作为可选添加.

例如:

如果省略类型规范,则会出现编译错误

defmodule Greeting do
  @callback hello(person)
end
# (CompileError) iex:82: type specification missing return type: hello(person)
Run Code Online (Sandbox Code Playgroud)

为了使编译器满意,我们必须包含类型规范:

defmodule Greeting do
  @callback hello(%Person{}) :: {:ok, String.t} | {:error, String.t}
end
Run Code Online (Sandbox Code Playgroud)

现在,当我们采用该行为时,编译器会检查function_name/arity已定义的内容:

defmodule WesternGreeting do
  @behaviour Greeting
  def hello(), do: "Howdy"
end
# warning: undefined behaviour function hello/1 (for behaviour Greeting)
Run Code Online (Sandbox Code Playgroud)

但是编译器会忽略@callback中的所有类型规范:

defmodule WesternGreeting2 do
  @behaviour Greeting
  def hello([a, b, c]), do: a <> b <> c
end
# No warnings or errors
Run Code Online (Sandbox Code Playgroud)

ape*_*223 0

它的原因@callback与 相同@spec,它需要类型。如果您在第一个示例中定义返回类型,它也会失败:

iex(1)> defmodule Greeting do
...(1)>   @callback hello(person) :: any()
...(1)> end
** (CompileError) iex:2: type person() undefined
Run Code Online (Sandbox Code Playgroud)

关于检查类型,我想还没有完成