这是一个老问题,但我相信只要有一点创意就可以正确回答:
问题的目的是
具有以下限制;
这可以通过以下方式解决;
使用第一个限制导致我们得到以下解决方案:
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,它可以执行具有给定参数的函数。
通过传递函数引用。到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 被调用以执行带有args 的fun()。
%% 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]).