例如,我想要一个可以这样调用的函数:
foo :bar, key: "value" do
"some block value"
end
或
foo key: "value" do
"some block value"
end
或
foo :bar do
"some block value"
end
或只是
foo key: "value"
首先,函数定义如下所示:
def foo(bar, opts \\ [], [do: block])
我需要适应的情况下,我只是传递选项而不是:bar,我得到编译错误。我完全理解为什么(opts \\ []
创建了更多与我的其他函数定义相匹配的函数)。那么,在某种程度上允许foo
方法工作的良好解决方法是什么?
答案 0 :(得分:4)
我将各种可能性定义为单独的arity函数,它使用3个值调用一个do_foo/3
函数。假设bar
永远不是一个列表(如果它可以是一个列表,那么对于arity 1和2来说整个事情就变得模棱两可了,因为我们无法知道该值是针对bar
还是{{1}你可以做类似的事情:
opts
输出:
defmodule A do
def foo(opts) when is_list(opts), do: do_foo(nil, opts, nil)
def foo(bar), do: do_foo(bar, nil, nil)
def foo(opts, [do: block]) when is_list(opts), do: do_foo(nil, opts, block)
def foo(bar, [do: block]), do: do_foo(bar, nil, block)
def foo(bar, opts, [do: block]), do: do_foo(bar, opts, block)
defp do_foo(bar, opts, block) do
IO.inspect {bar, opts, block}
end
end
A.foo :bar, key: "value" do
"some block value"
end
A.foo key: "value" do
"some block value"
end
A.foo :bar do
"some block value"
end
A.foo key: "value"