我知道Elixir在需要忽略这些参数时会使用下划线作为参数。我的问题是,为什么要这些呢?
def photos(_,_,_) do
{:ok, Instagram.Posts.list_photos}
end
def photo(_, %{id: id}, _) do
{:ok, Instagram.Posts.get_photo!(id)}
end
在这个示例中,我已经编写了一个方法(来自教程)接受三个参数,现在没有使用它们,因此下划线但为什么没有空括号?在第二个例子中,我使用了Id参数而不是其他参数,为什么我仍然需要下划线?
答案 0 :(得分:4)
你是对的。如果我们根本不使用它们,我们可以设置不带参数的函数:
def f() do
# Do something...
end
然而,Elixir及其父母Erlang与他们的arity一起识别功能;如果我们在某些时候使用同一函数中的部分或全部参数,我们需要一种方法来识别设置哪些参数以及如何设置。
在Elixir,这:
def f(a) do
# ...
end
不同的功能而不是:
def f() do
# ...
end
前者为f/0
,后者为f/1
。现在,正如您似乎熟悉的那样,这里是模式匹配的一个例子:
def f(:flag, b) when is_number(b) do
# paramater 'a' is set as :flag
# and 'b' is a number, do
# something with 'b' ...
end
def f(:flag, b) do
# paramater 'a' is set as :flag
# and 'b' is not a number, do
# something with 'b' ...
end
def f(a, :flag) do
# paramater 'a' is not set as :flag
# but 'b' is,
# do something with 'a' ...
end
def f(_, _) do
# otherwise, we don't care
# what 'a' and 'b' are, maybe
# do something...
end
但是,你是对的,我们可以在技术上在调用者函数中执行这些检查,并在适当的时候调用f/0
(而不是与我们的任何一个都不匹配的f(a, b)
初始检查)我们将与f/2
分开定义。但是,我们可能会失去Elixir提供的语法便利和优雅。
答案 1 :(得分:1)
让系统知道你知道变量在那里但你不会使用它。如果你不使用下划线开始名称而不使用变量,你将得到编译时警告,变量未被使用。
例如,您将一个数字除以另一个数字后,您可以除以0.因此,您的代码将如下所示:
divide(_A, 0) -> "can't do";
divide(A, B) -> A/B.
我们使用相同的函数,但它使用模式匹配来过滤掉0.因为你不会使用第一个数字,所以用下划线命名它,告诉编译器忽略这个事实。