我正在尝试编写和编译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_server(选中它)在传递它后保留其回调模块名称:gen_server:start_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);
...
它应用init/1
保留在Mod
参数中的传递的回调模块,获取其最后一个值,执行所需的操作并继续执行(或不取决于最后一个值)。
假设我们有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([]),
...
有很多方法可以这样做。
如您所见,这里没有魔术。即使没有-behaviour(bla)
也未指定回调,此方法也可以使用-callback
。这只是有关编译器,工具和文档的信息。
来自erlang文档:行为
顺便说一句。start_link
函数应该产生另一个进程并链接到该进程。
start_link(Mod) ->
spawn_link(Mod, init, [[]]).
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句