erlang - 无法在 Erlang 中创建规范

标签 erlang

我试图在 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.erlbar.erl 声明为foo_bar 类型的行为:

-module(foo_bar).

-callback frob(integer(), inet:socket()) -> ok.

然后……

-module(foo).
-behavior(foo_bar).

frob(A, B) ->
    % ...

如果模块 foo 缺少指定类型的函数 frob/2,则会抛出警告,因为它无法匹配其声明的行为。

这对于简化检查、管理和保持有组织的模块间 API 兼容性的方式非常有用。另请注意,您可以在模块中定义任意数量的回调,并且可以在模块中声明任意数量的行为。

参见:How to create and use a custom Erlang behavior?

关于erlang - 无法在 Erlang 中创建规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46414994/

相关文章:

c++ - 将 Erlang 与 C++ 集成

Erlang Gen_call vs Gen_cast

erlang - 在 Erlang 中,如何独立捕获子进程的 stdout 和 stderr?

Erlang pid 比较保证

database - 从不同节点访问分布式 mnesia 数据库

erlang - Erlang 有完整的 REPL 吗?

orm - 什么取代了函数式编程中的 MVC 模式?

erlang - 如何让行为回调函数不被实现?

erlang - Unix 域套接字如何在 Erlang 19 中工作

erlang - 如何在不关闭 erlang VM 的情况下离开 erlang shell