首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Erlang -callbacks只能通过MFA函数调用(应用/3、派生/3、.)吗?(自定义行为如何)

Erlang -callbacks只能通过MFA函数调用(应用/3、派生/3、.)吗?(自定义行为如何)
EN

Stack Overflow用户
提问于 2018-11-14 09:35:06
回答 2查看 223关注 0票数 0

这就是我对这个简单代码的怀疑

代码语言:javascript
复制
-module(simple_server).
-export( [sayHello/0] ).

-callback say(Num :: term()) -> term().

sayHello() ->
    io:fwrite( "Hello 1: ~p\n", [ say(1) ]) ,
    io:fwrite( "Hello 2: ~p\n", [ say(2) ]) .

未能汇编:

代码语言:javascript
复制
$ erlc simple_server.erl
simple_server.erl:7: function say/1 undefined
simple_server.erl:8: function say/1 undefined

如果是这样的话,那么在其他地方没有显式的注释:官方文件“学二郎”这个答案

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-14 11:14:56

您需要提供回调模块的名称,这可以通过applyspawn完成,但也可以使用变量作为模块名进行简单调用,例如CallbackModule:say(1)

所以你可以这样做:

代码语言:javascript
复制
sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~p\n", [ CallbackModule:say(1) ]) ,
    io:fwrite( "Hello 2: ~p\n", [ CallbackModule:say(2) ]) .

代码语言:javascript
复制
sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~p\n", [ apply(CallbackModule, say, [1]) ]) ,
    io:fwrite( "Hello 2: ~p\n", [ apply(CallbackModule, say, [2]) ]) .

这两个版本是等价的。

让我们创建一个实现simple_server行为的回调模块:

代码语言:javascript
复制
-module(my_callback).
-behaviour(simple_server).
-export([say/1]).

say(N) ->
    {N, is, the, loneliest, number}.

现在,我们可以使用模块名作为参数调用simple_server:sayHello

代码语言:javascript
复制
> simple_server:sayHello(my_callback).
Hello 1: {1,is,the,loneliest,number}
Hello 2: {2,is,the,loneliest,number}
票数 2
EN

Stack Overflow用户

发布于 2018-11-14 11:52:53

HOWTO Erlang自定义行为(模板方法模式).

-1。编写一个通用模块。这里定义了一个算法,但是一些步骤( Erlang命名中的回调函数)将留给将来的特定定义。

代码语言:javascript
复制
%% generic.erl   
-module(generic).
-export( [sayHello/1] ).

-callback say(Num :: term()) -> term(). %% future definition

%% generic algorithm: needs the reference to the provider module                                 
sayHello(ProviderModule) ->
  io:fwrite( "Hello 1: ~p\n", [ ProviderModule:say(1) ]) ,
  io:fwrite( "Hello 2: ~p\n", [ ProviderModule:say(2) ]) .

-2.编译generic.erl

代码语言:javascript
复制
erlc generic.erl

-(3.)尝试编写提供程序(回调)模块

代码语言:javascript
复制
%% callbacks1.erl (fails to implement say/1 callback)
-module( callbacks1 ).
-behaviour( generic ).

-(4.)编译callbacks1.erl:使用-pa .来表示generic.beam在哪里。(因此,发出了有关say/1的预期警告)。

代码语言:javascript
复制
erlc -pa . callbacks1.erl
callbacks1.erl:2: Warning: undefined callback function say/1 (behaviour 'generic')

(注意:如果没有给出-pa,您将得到以下内容:"callbacks1.erl:2:警告:行为一般未定义“)

-3.编写正确的提供程序(回调)模块。

代码语言:javascript
复制
%% callbacks2.erl
-module( callbacks2 ).
-behaviour( generic ).

-export( [say/1] ).

say(1) -> "good morning";
say(2) -> "bon jour";
say(_) -> "hi".

-4.编译它

代码语言:javascript
复制
erlc -pa . callbacks2.erl

(好了)

-5.编写一个main.erl来收集带有回调模块的泛型模块。

代码语言:javascript
复制
%% main.erl
-module( main ).
-export( [main/0] ).

main() ->
    %% call the generic algorithm telling it what callback module to use
    generic:sayHello( callbacks2 ) 
    . % ()

-6.编译和运行main

代码语言:javascript
复制
erlc main.erl
erl -noshell -s main main -s init stop

我们得到:

代码语言:javascript
复制
Hello 1: "good morning"
Hello 2: "bon jour"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53296965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档