erlang - Erlang 中的参数化模块有哪些替代方案?

标签 erlang

我可以看到为什么参数化模块被如此使用,因为它们允许我们执行以下操作:

X = y:new("param").

X:action1().
X.get_property():

: 感觉很OO。但是,这只是 Erlang 中的一个实验性功能,我听说它可能会被删除,所以我需要找到一个替代方案。

最佳答案

参数化模块只不过是函数第一个参数的快捷方式。看这两个例子:

-module(y, [Name,Age]).
-compile(export_all).

action1() -> io:format("Hello, ~p!~n",[Name]).

get_age() -> Age.

运行:
1> c(y).
{ok,y}
2> X = y:new("Fred",22).
{y,"Fred",22}
3> X:action1().
Hello, "Fred"!
ok
4> X:get_age().
22

现在没有参数化的东西:
-module(y).
-compile(export_all).

action1([Name,_]) -> io:format("Hello, ~p!~n",[Name]).

get_age([_,Age]) -> Age.

运行它:
1> c(y).
{ok,y}
2> X = ["Fred",22].
["Fred",22]
3> y:action1(X).
Hello, "Fred"!
ok
4> y:get_age(X).
22

参数化模块的最大“优势”是您将携带状态的负担从变量转移到模块名称。对于不习惯“Erlang 方式”的人来说,这看起来要简单得多,但它与传统的代码风格相冲突。

这不仅仅是实验与否的问题。你抛弃了引用透明性,不可变变量的语义变得有点奇怪。一个很好的例子是假设您将以下函数添加到参数化模块:
ret_fn() -> fun(Age) -> Age + 5 end.

编译模块时,您会收到警告 ./y.erl:8: Warning: variable 'Age' shadowed in 'fun' .这是警告您在匿名函数的 head 子句中使用预定义变量的名称。然而,快速浏览ret_fn/0函数绝对没有显示该变量来自何处的迹象。

现在假设您使用变量 Name用于任何其他目的;你会得到一个运行时错误告诉你** error: no match of right hand side value < ... > .

我要说的一点是,参数化模块减少了您需要做的输入量,但以牺牲逻辑简单性为代价。不仅为您,也为任何其他 Erlang 程序员处理您的代码。

最重要的是,dialyzer、TypEr、tidiers 等工具并不能保证支持这些惯用语。这些工具也非常有用!不要解雇他们。 (编辑:较新版本的 Erlang (R13B04+) 现在保证支持)

参数化模块的最佳替代方案是避免使用它们并使用 mochiweb 之外的所有其他 Erlang 程序员正在使用的东西。

关于erlang - Erlang 中的参数化模块有哪些替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2291155/

相关文章:

module - 我可以获得当前加载的所有模块的列表吗?

erlang:分布式哈希表?

python - 事件关联和过滤——如何,从哪里开始?

list - Erlang : flattening a list of strings

erlang - 如何知道 .beam 文件是否使用 debug_info 编译?

linux - Erlang App 不做项目

erlang - 在Erlang中回溯

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

syntax - '->'之前的语法错误,无明显原因

Erlang gen_server 转换错误的返回值