使用默认值和/或没有特定顺序的 Erlang 函数调用
Erlang Function call with default values and or without specific order
我是 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]
我在地图到达之前经常看到的一种方法是:
- 带有可选参数的 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}
这有点尴尬,主要是因为记录是元组的编译时语法糖。不过,您可以使用地图做更优雅的事情。
P.S。没有对此进行测试,因此可能包含一些错误。
P.P.S。如果您传递未知选项,它将抛出异常。
我是 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]
我在地图到达之前经常看到的一种方法是:
- 带有可选参数的 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}
这有点尴尬,主要是因为记录是元组的编译时语法糖。不过,您可以使用地图做更优雅的事情。
P.S。没有对此进行测试,因此可能包含一些错误。
P.P.S。如果您传递未知选项,它将抛出异常。