Elixir 函数中的元组或关键字列表
Tuples or Keyword Lists in Elixir functions
Programming Elixir 书的第 221 页指出,如果我们想将 call
中的多个值传递给 GenServer
,我们应该使用元组:
def handle_call({:set_number, new_number}, _from, _current_number) do
{ :reply, new_number, new_number }
end
iex> GenServer.call(pid, {:set_number, 999})
在我看来,关键字列表更适合这种情况:
def handle_call([ set_number: new_number ], _from, _current_number) do
{ :reply, new_number, new_number + 1 }
end
iex(2)> GenServer.call pid, set_number: 999
这样我就可以完全避免大括号,而且我使用关键字列表的目的似乎是:传递 options/arguments。
这种做法有什么问题吗?还是我违反了一些最佳实践?
Keyword Lists 是 2 项元组的列表。所以 [set_number: 999]
等同于 [{:set_number, 999}]
.
通常在这些情况下使用元组,因为它们比关键字列表更通用。关键字列表仅限于 2 项元组,而在某些情况下您想要传递 3 项元组(或更多)。考虑存储键值 GenServer
的情况。要存储一个值,您需要以 {:put, key, value}
.
的形式传递一个 3 项元组
"Avoiding braces altogether" 不应该是所用数据类型的决定因素。另请注意,客户端不应该知道服务器实现,因此,您通常定义一个客户端 API.
defmodule MyModule do
use GenServer
#client API
def set_number(pid, number) do
GenServer.call(pid, {:set_number, number})
end
def handle_call({:set_number, new_number}, _from, _current_number) do
{ :reply, new_number, new_number }
end
end
现在从 iex
开始,您只需调用:
iex > MyModule.set_number(pid, 999)
这样,如果您需要更改服务器实现,则无需更改客户端。
Programming Elixir 书的第 221 页指出,如果我们想将 call
中的多个值传递给 GenServer
,我们应该使用元组:
def handle_call({:set_number, new_number}, _from, _current_number) do
{ :reply, new_number, new_number }
end
iex> GenServer.call(pid, {:set_number, 999})
在我看来,关键字列表更适合这种情况:
def handle_call([ set_number: new_number ], _from, _current_number) do
{ :reply, new_number, new_number + 1 }
end
iex(2)> GenServer.call pid, set_number: 999
这样我就可以完全避免大括号,而且我使用关键字列表的目的似乎是:传递 options/arguments。
这种做法有什么问题吗?还是我违反了一些最佳实践?
Keyword Lists 是 2 项元组的列表。所以 [set_number: 999]
等同于 [{:set_number, 999}]
.
通常在这些情况下使用元组,因为它们比关键字列表更通用。关键字列表仅限于 2 项元组,而在某些情况下您想要传递 3 项元组(或更多)。考虑存储键值 GenServer
的情况。要存储一个值,您需要以 {:put, key, value}
.
"Avoiding braces altogether" 不应该是所用数据类型的决定因素。另请注意,客户端不应该知道服务器实现,因此,您通常定义一个客户端 API.
defmodule MyModule do
use GenServer
#client API
def set_number(pid, number) do
GenServer.call(pid, {:set_number, number})
end
def handle_call({:set_number, new_number}, _from, _current_number) do
{ :reply, new_number, new_number }
end
end
现在从 iex
开始,您只需调用:
iex > MyModule.set_number(pid, 999)
这样,如果您需要更改服务器实现,则无需更改客户端。