我试图在 Erlang 模块中创建一个非常简单的规范,但出现此错误。
spec for undefined function compare/2
这是我的代码:
-module(spec_example).
-spec compare(any(), any()) -> less | equal | greater.
-record(heap_node, { item :: any(),
children :: [#heap_node{}] }).
-record(priority_queue, { root :: #heap_node{} | nil,
comparer :: compare() }).
我无法在这里定义比较函数,因为它将作为外部参数提供。我找到了similar examples在 GitHub 中,我想它们都工作正常。
我已经在模块和头文件中尝试过此操作,但错误是相同的。我一定错过了一些非常基本的东西。
最佳答案
您引用的示例是头文件 (.hrl),而不是源文件 (.erl),并且他们将其导入到应该以某种方式运行的文件的顶部。
这似乎是强制少数模块都以相同方式运行的一种方式。这让我很困惑,因为这种行为定义正是存在的行为要处理的。
另外,请注意,他们的 api.hrl
还导入 wf.hrl
,然后这些是 imported all over the place in the project 。据我所知,浏览该代码确实没有理由不将其定义为一种行为。 (可能有一个原因,但从代码中看并不明显......而且我想不出避免在这种情况下使用行为的好理由。)
功能规范
定义函数规范时,您需要有一个基础函数来用它进行注释。所以这本身就是非法的:
-spec add(integer(), integer()) -> integer().
但这是合法的:
-spec add(integer(), integer()) -> integer().
add(A, B) ->
A + B.
使用类型、规范、edoc 等的示例:https://github.com/zxq9/zuuid
定义行为
那么“什么是行为?”假设您希望在程序中有一处可以动态选择要调用的模块,并且您必须期望该模块的行为方式与其他类似定义的模块相同。如果您需要调用 foo:frob/2
,它的工作方式应该与 bar:frob/2
完全相同(就类型而言)。因此,我们可能会在 foo_bar.erl
内部的某个地方编写一个行为定义,然后将我们的模块 foo.erl
和 bar.erl
声明为foo_bar
类型的行为:
-module(foo_bar).
-callback frob(integer(), inet:socket()) -> ok.
然后……
-module(foo).
-behavior(foo_bar).
frob(A, B) ->
% ...
如果模块 foo
缺少指定类型的函数 frob/2
,则会抛出警告,因为它无法匹配其声明的行为。
这对于简化检查、管理和保持有组织的模块间 API 兼容性的方式非常有用。另请注意,您可以在模块中定义任意数量的回调,并且可以在模块中声明任意数量的行为。
关于erlang - 无法在 Erlang 中创建规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46414994/