【问题标题】:Create new guard clause创建新的保护子句
【发布时间】:2018-07-02 14:06:14
【问题描述】:

在 Elixir 中,我将如何为函数创建新的保护子句?显然,我已经看到您不能只在 when 语句中调用任何函数,但是能够执行这样的操作会很好:

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

【问题讨论】:

  • pattern 匹配 arg 中的卡片到 play_card: def play_card(play_card(player=Player[cards:cards]) when is_list(cards)

标签: function pattern-matching elixir


【解决方案1】:

简短的回答是:你不能。

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

有效守卫列表可以在入门指南中找到:http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses

“复杂”保护宏的示例实现可以在 Elixir 源代码中找到:https://github.com/elixir-lang/elixir/blob/5d34fcdccd20bf38c4f2a13f8adeb78e22b4e74c/lib/elixir/lib/kernel.ex#L1574

【讨论】:

【解决方案2】:

您现在可以使用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

文档:https://hexdocs.pm/elixir/Kernel.html#defguard/1

但是,必要性守卫仍然是非常简单的构造,因此您不能真正将复杂的逻辑放入其中。作为参考,您可以在守卫中添加以下内容:https://hexdocs.pm/elixir/master/guards.html#list-of-allowed-expressions

【讨论】:

    猜你喜欢
    • 2010-12-08
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    相关资源
    最近更新 更多