在Erlang中编写和编译自定义行为

在Erlang中编写和编译自定义行为,erlang,Erlang,我正试图在Erlang中编写和编译一个自定义行为 我找不到任何关于如何编译这种行为的清晰文档 -module(bla). -export([start_link/0,behaviour_info/1]). behaviour_info(callbacks)-> [{init,1}]; behaviour_info(_Other)-> undefined. %% -callback init(Args :: term()) -> %% {ok, St

我正试图在Erlang中编写和编译一个自定义行为

我找不到任何关于如何编译这种行为的清晰文档

-module(bla).

-export([start_link/0,behaviour_info/1]).

behaviour_info(callbacks)->
    [{init,1}];
behaviour_info(_Other)->
    undefined.

%% -callback init(Args :: term()) ->
%%     {ok, State :: term()} | {ok, State :: term(), timeout()} |
%%     {stop, Reason :: term()} | ignore.

start_link()->
    init([]).
我的喜剧指挥是:

erlc.exe .\src\bla.erl
结果:

bla.erl:24: function init/1 undefined

有人想知道如何在erlang中编写和编译行为吗?任何链接?

定义行为回调会导致您对回调模块的实现负有义务。在erlang中,模块只是函数容器,而不是类或接口。行为基于运行时模块名称解析
Mod:fun()
。OTP(检查它)在您将其传入后保留其回调模块名称:
gen\u server:start\u link(CallbackModuleName、Args、Opts)
,下面是
init/1的代码:

init_it(Starter, Parent, Name0, Mod, Args, Options) ->
    Name = name(Name0),
    Debug = debug_options(Name, Options),
    case catch Mod:init(Args) of
        {ok, State} ->
            proc_lib:init_ack(Starter, {ok, self()}),
            loop(Parent, Name, State, Mod, infinity, Debug);
        {ok, State, Timeout} ->
            proc_lib:init_ack(Starter, {ok, self()}),
            loop(Parent, Name, State, Mod, Timeout, Debug);
        ...
它应用保存在
Mod
参数中的已传递回调模块的
init/1
,获取其最后一个值,执行您想要的操作并继续(或不执行,取决于最后一个值)

假设我们有模块
bla_impl
,如下所示:

-module(bla_impl).
-behaviour(bla).
-export([init/1, start_link/0]).

start_link() -> bla:start_link(?MODULE). %% macro ?MODULE is resolved to bla_impl
init(Args) -> ... .
现在,您需要在bla中说明您使用的模块:

-module(bla).
-export([start_link/1]).

start_link(Mod) -> Mod:init([]).
或者更好的解决方案是从配置中读取:

-module(bla).
-export([start_link/0]).

start_link() -> 
    Mod = application:get_env(bla_app,  callback_module),
    Mod:init([]),
    ...
有很多方法可以做到这一点

正如你所看到的,这里没有魔法。即使没有
-behavior(bla)
或使用
-callback
指定回调,这也可以工作。这只是编译器、工具和文档的信息

从erlang文档:

顺便说一句,
start\u link
函数应该生成另一个进程并链接到它

start_link(Mod) ->
    spawn_link(Mod, init, [[]]).

知道了!真的没有魔法!感谢卢卡斯的快速而清晰的回答。