似乎在定义行为时,您必须在@callback
定义中包含类型规范。然后,当您采用该行为时,编译器要求定义function_name/arity
,但如果您不遵循类型规范,则非常高兴。
我的问题是:
@callback
会将类型规格与检查function_name/arity
定义的实际功能结合起来?这使得很难理解什么是文档以及什么是核心功能。 Elixir的其余部分似乎清楚地将两者分开,将类型规格作为可选添加。例如:
如果省略类型规范,我们会收到编译错误
defmodule Greeting do
@callback hello(person)
end
# (CompileError) iex:82: type specification missing return type: hello(person)
为了让编译器满意,我们必须包含类型规范:
defmodule Greeting do
@callback hello(%Person{}) :: {:ok, String.t} | {:error, String.t}
end
现在,当我们采用该行为时,编译器会检查function_name/arity
是否已定义:
defmodule WesternGreeting do
@behaviour Greeting
def hello(), do: "Howdy"
end
# warning: undefined behaviour function hello/1 (for behaviour Greeting)
然而,编译器会忽略@callback中的所有类型规范:
defmodule WesternGreeting2 do
@behaviour Greeting
def hello([a, b, c]), do: a <> b <> c
end
# No warnings or errors
答案 0 :(得分:0)
原因@callback
与@spec
相同,它需要类型。
如果您将在第一个示例中定义返回类型,它也将失败:
iex(1)> defmodule Greeting do
...(1)> @callback hello(person) :: any()
...(1)> end
** (CompileError) iex:2: type person() undefined
关于检查类型,我认为还没有完成
答案 1 :(得分:0)
在旧版本的erlang中,它不是必需的。沿线的某个地方(我不记得确切的时间),人们意识到,如果添加它们,则Dialyzer可以进行一些其他验证。
此外,您实际上可以在运行时从具有某些用途的模块中获取类型。