这是一个老问题,但我相信可以通过一点创造力来正确回答:
问题的目标是
具有以下限制;
这可以通过以下方式解决;
使用第一个限制使我们得到以下解决方案:
run() ->
Module = module,
Function = function,
Args = [arg1, arg2, arg3],
erlang:spawn(Module, Function, Args).
但是,在此解决方案中,需要导出该功能。
使用第二个限制(不导出调用的函数)和第一个限制我们使用传统的 erlang 逻辑得到以下解决方案:
run() ->
%% Generate an anonymous fun and execute it
erlang:spawn(fun() -> function(arg1, arg2, arg3) end).
由于垃圾收集器需要执行的额外工作,此解决方案会在每次执行时生成匿名乐趣,根据您的设计可能需要也可能不需要(请注意,通常,这可以忽略不计,问题可能只会在更大系统)。
在不生成匿名乐趣的情况下编写上述内容的另一种方法是生成一个erlang:apply/2
可以执行具有给定参数的函数的函数。
通过传递函数参考。to erlang:apply/2
,我们可以引用一个本地函数并使用给定的参数调用它。
下面实现了这个解决方案:
run() ->
%% Function Ref. to a local (non-exported) function
Function = fun function/arity,
Args = [arg1, arg2, arg3],
erlang:spawn(erlang, apply, [Function, Args]).
编辑:这种类型的解决方案可以在Erlang Src中找到,erlang:apply/2
它被调用以执行fun()
带有 args 的 a。
%% https://github.com/erlang/otp/blob/71af97853c40d8ac5f499b5f2435082665520642/erts/preloaded/src/erlang.erl#L2888%% Spawn and atomically set up a monitor.
-spec spawn_monitor(Fun) -> {pid(), reference()} when
Fun :: function().
spawn_monitor(F) when erlang:is_function(F, 0) ->
erlang:spawn_opt(erlang,apply,[F,[]],[monitor]);
spawn_monitor(F) ->
erlang:error(badarg, [F]).