【发布时间】:2019-09-12 15:41:52
【问题描述】:
我有一个关于默认参数和 nil 值的一般性问题。假设我有两个功能。一个调用另一个(这是一个辅助函数)。两者都有一个可选参数。
helper 函数只是将一个列表连接到一个带有连接器的字符串。 joiner 被传递给 opts 关键字列表中的第一个函数。 joiner 的传递是可选的,默认为"AND"
defmodule ParamTest do
def func_1(list, opts \\ []) do
helper(list, opts[:joiner])
# Do something else with the result
end
defp helper(list, joiner \\ "AND") do
Enum.join(list, " #{joiner} ")
end
end
# Example 1
["el 1", "el 2"]
|> ParamTest.func_1(joiner: "AND")
# Result "el 1 AND el 2"
# Example 2
["el 1", "el 2"]
|> ParamTest.func_1
# Result: "el 1 el 2"
# But it should be also "el 1 AND el 2"
问题是:在第二个示例中 opts[:joiner] 将为零。但它仍然存在,因此不会使用默认值。
一种可能的解决方案是使用case:
defmodule ParamTest do
def func_1(list, opts \\ []) do
case is_nil(opts[:joiner]) do
true -> helper(list)
false -> helper(list, opts[:joiner])
end
# Do something else with the result
end
defp helper(list, joiner \\ "AND") do
Enum.join(list, " #{joiner} ")
end
end
另一种方法是为帮助程序使用两个函数定义并使用模式匹配:
defmodule ParamTest do
def func_1(list, opts \\ []) do
case is_nil(opts[:joiner]) do
true -> helper(list)
false -> helper(list, opts[:joiner])
end
end
defp helper(list, nil) do
Enum.join(list, " AND ")
end
defp helper(list, joiner \\ "AND") do
Enum.join(list, " #{joiner} ")
end
end
但我觉得这不是很优雅,在更复杂的情况下可能会变得混乱。
对于这种情况有什么更好的解决方案?
【问题讨论】:
标签: elixir