Erlang gen_服务器:调用与直接调用函数

Erlang gen_服务器:调用与直接调用函数,erlang,Erlang,假设gen_服务器中运行两个进程(由主管启动)。一个调用另一个中的函数,如下所示:brother:function(Param)。它还可以执行genu服务器:call(brother,Param)。每个应用程序的用例是什么?在这两种情况下,第一个进程都会等待brother中的函数完成,因此我不知道何时应该使用每个函数 第一个进程等待brother中的函数完成 不,没有。或者更确切地说,这取决于如何定义函数。通常是这样的 function(Param) -> gen_server:call(

假设gen_服务器中运行两个进程(由主管启动)。一个调用另一个中的函数,如下所示:
brother:function(Param)
。它还可以执行
genu服务器:call(brother,Param)
。每个应用程序的用例是什么?在这两种情况下,第一个进程都会等待
brother
中的函数完成,因此我不知道何时应该使用每个函数

第一个进程等待brother中的函数完成

不,没有。或者更确切地说,这取决于如何定义
函数。通常是这样的

function(Param) -> gen_server:call(?MODULE, {function, Param}) 
%% or gen_server:call(?MODULE, Param) if there's only one kind of request
实际的实现将在
brother:handle\u call

显然,在这种情况下,调用
brother:function(Param)
或手动执行
genu server:call
的结果没有区别,但是调用
brother:function
是一种更好的做法:它允许隐藏调用模块不需要知道的细节,并允许
brother
进行更改

第一个进程等待brother中的函数完成

不,没有。或者更确切地说,这取决于如何定义
函数。通常是这样的

function(Param) -> gen_server:call(?MODULE, {function, Param}) 
%% or gen_server:call(?MODULE, Param) if there's only one kind of request
实际的实现将在
brother:handle\u call


显然,在这种情况下,调用
brother:function(Param)
或手动执行
genu server:call
的结果没有区别,但是调用
brother:function
是一种更好的做法:它允许隐藏调用模块不需要知道的细节,并允许
brother
更改。

直接没有任何区别。但是,直接使用
gen\u服务器:call
(或
cast
)意味着您将其他模块绑定到
gen\u服务器的内部。想象一下,稍后,您希望更改
brother
的注册,以便它使用其他内容(例如,一个外部库,如gproc)。现在,您必须找到使用gen_server的每个地方:调用(兄弟,…)
并修复它,复制大量代码以获取服务器名称等等。总的来说,拥有
brother:function(…)

这同样适用于更改调用或强制转换的内部结构。只需将所有内容作为参数传递给函数,然后使用该函数构造参数就变得容易多了。比如,假设您使用该函数创建模块内部的记录


所以总的来说,它主要是关于关注点的封装和分离。该模块通常应负责找到适当的服务器以发送呼叫,以及呼叫的适当格式。

直接没有任何区别。但是,直接使用
gen\u服务器:call
(或
cast
)意味着您将其他模块绑定到
gen\u服务器的内部。想象一下,稍后,您希望更改
brother
的注册,以便它使用其他内容(例如,一个外部库,如gproc)。现在,您必须找到使用gen_server的每个地方:调用(兄弟,…)
并修复它,复制大量代码以获取服务器名称等等。总的来说,拥有
brother:function(…)

这同样适用于更改调用或强制转换的内部结构。只需将所有内容作为参数传递给函数,然后使用该函数构造参数就变得容易多了。比如,假设您使用该函数创建模块内部的记录


所以总的来说,它主要是关于关注点的封装和分离。该模块通常应负责找到适当的服务器以发送呼叫,以及呼叫的适当格式。

如果gen_server:call位于同一模块中,为什么还要使用它?我们不能在函数中执行您在调用中执行的任何操作吗,因为无论哪种方式,我们都在等待完成?有时您不能这样做,因为您的gen_服务器保持着其他进程不知道的状态(handle_call的第三个参数)。有时是,但通常情况下,您的
gen_服务器将封装一些您不想向其他进程透露的状态。本质上,与OOP中的
静态
函数和常规方法相同。如果gen_server:在同一个模块中,为什么还要调用它?我们不能在函数中执行您在调用中执行的任何操作吗,因为无论哪种方式,我们都在等待完成?有时您不能这样做,因为您的gen_服务器保持着其他进程不知道的状态(handle_call的第三个参数)。有时是,但通常情况下,您的
gen_服务器将封装一些您不想向其他进程透露的状态。它本质上与OOP中的
静态
函数和常规方法的区别相同。