为什么在Elixir中使用下划线作为参数,而不是根本没有参数?

时间:2018-02-01 22:33:10

标签: elixir phoenix-framework

我知道Elixir在需要忽略这些参数时会使用下划线作为参数。我的问题是,为什么要这些呢?

def photos(_,_,_) do
    {:ok, Instagram.Posts.list_photos}
end

def photo(_, %{id: id}, _) do
    {:ok, Instagram.Posts.get_photo!(id)}
end

在这个示例中,我已经编写了一个方法(来自教程)接受三个参数,现在没有使用它们,因此下划线但为什么没有空括号?在第二个例子中,我使用了Id参数而不是其他参数,为什么我仍然需要下划线?

2 个答案:

答案 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.因为你不会使用第一个数字,所以用下划线命名它,告诉编译器忽略这个事实。