Function 创建新的保护子句

Function 创建新的保护子句,function,pattern-matching,elixir,Function,Pattern Matching,Elixir,在Elixir中,我将如何为函数创建新的guard子句?显然,我已经看到,当语句时,您不能只调用语句中的任何函数,但能够这样做会很好: defmodule Player do def play_card(player), do: [] def play_card(player) when has_cards(player), do: ... # Define has_cards as guard clause? end 简单的回答是:你不能 答案很长,您可以定义宏,只要宏由有效的g

在Elixir中,我将如何为函数创建新的guard子句?显然,我已经看到,当语句时,您不能只调用
语句中的任何函数,但能够这样做会很好:

defmodule Player do
  def play_card(player), do: []
  def play_card(player) when has_cards(player), do: ...
  # Define has_cards as guard clause?
end

简单的回答是:你不能

答案很长,您可以定义宏,只要宏由有效的guards表达式组成,它们就可以在guards中工作。但对于复杂的守卫来说,这并不是小事,所以最好避免,除非你真的必须这样做

可以在《入门指南》中找到有效防护装置的列表:


“复杂”保护宏的示例实现可以在Elixir源代码中找到:

您现在可以使用
Kernel.defguard/1
(或
defguardp/1
)执行此操作:

defmodule Player do
  defstruct [:name, cards: []]
  defguard has_cards(cards) when cards != []

  def play_card(%__MODULE__{cards: cards}) when has_cards(cards), do: []
  def play_card(_player), do: []
end
文件:


然而,必要的防护措施仍然是非常简单的结构,因此您不能真正将复杂的逻辑放入其中。作为参考,您可以在guards中添加以下内容:

模式匹配arg中的牌来玩\u card:def play\u card(player=player[cards:cards])当是\u list(cards)时,还有另一个很好的例子repo
是男性的
是女性的
宏被用作守卫。关于这一点的另一个很好的参考是,但请务必查看Elixir关于此的命名约定:。复杂保护宏名称的形式应为
is_ux]
而不是
[x]?