我是 Erlang 新手,试图找出函数调用的默认值的最佳方法,这需要多个变量和/或也不想按特定顺序输入参数。我目前正在使用这种基于 Clojure 方式的松散格式。在Erlang中是否有更好的方式或方法来实现这一点?我还提供了一个 Clojure 示例作为引用:
Erlang 版本:
some_function_with_defaults() ->
some_function_with_defaults(#{}).
some_function_with_defaults(Map) ->
Defaults = #{
arg1 => 0, % arg1 default value
arg2 => 1, % arg2 default value
arg3 => 2 % arg3 default value
},
Arguments = maps:merge(Defaults,Map),
#{arg1 := Arg1} = Arguments,
#{arg2 := Arg2} = Arguments,
#{arg3 := Arg3} = Arguments,
%% Do something with arguments
[Arg1,Arg2,Arg3].
%% Example call using only defaults
%% some_function_with_defaults().
%%
%% [0,1,2]
%% Example call specifying a specific value
%% some_function_with_defaults(#{arg1 => 99}).
%%
%% [99,1,2]
Clojure 引用:
(defn some-function-with-defaults
[
& {:keys
[
arg1
arg2
arg3
]
:or
{
arg1 0 ;; arg1_default_value
arg2 1 ;; arg2_default_value
arg3 2 ;; arg3_default_value
}
}
]
;; Do something with arguments
[arg1,arg2,arg3]
)
;; Example call using only defaults
;; (some-function-with-defaults)
;;
;; [0,1,2]
;; Example call specifying a specific value
;; (some-function-with-defaults :arg1 99)
;;
;; [99,1,2]
最佳答案
在 map 出现之前我经常看到的方法之一是:
- 带有可选参数的 proplist
- 使用默认值记录
- 函数从 proplist 中获取值并将其放入记录中。
-record(options, {
opt_int = 42 :: integer(), % default is 42
opt_bool = false :: boolean(), % default false
opt_atom :: undefined | val % default undefined
}).
parse_opts(Opts) ->
parse_opts(Opts, #options{}).
parse_opts([], Res) ->
Res;
parse_opts([{opt_int, Val} | RestOpts], Res) when is_integer(Val) ->
parse_opts(RestOpts, Res#options{opt_int = Val});
parse_opts([{opt_bool, Val} | RestOpts], Res) when is_boolean(Val) ->
parse_opts(RestOpts, Res#options{opt_bool = Val});
parse_opts([{opt_atom, Val} | RestOpts], Res) when Val == undefined; Val == val ->
parse_opts(RestOpts, Res#options{opt_atom = Val}).
parse_opts([{opt_int, 55}])
会给你 #options{opt_int = 55, opt_bool = false, opt_atom = undefined}
这有点尴尬,主要是因为记录是元组的编译时语法糖。不过,您可以使用 map 做更优雅的事情。
附注没有对此进行测试,因此可能包含一些错误。
P.P.S。如果您传递未知选项,它将抛出异常。
关于function - 使用默认值和/或没有特定顺序的 Erlang 函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31774961/