【问题标题】:Why we cant use other functions in Elixir guard clauses or macros?为什么我们不能在 Elixir 保护子句或宏中使用其他函数?
【发布时间】:2017-06-10 03:59:22
【问题描述】:

下面的代码显示了我所询问的示例: 为什么 Map、Enum 等...不能在保护子句或我自己的宏中使用。

defmodule GuardMod do
    defmacro has_any_key(arg, keys) do
        quote do
            Map.keys(unquote(arg), unquote(keys)) |> Enum.any?
        end
    end
end

defmodule OtherMod do
    import GuardMod

    @doc """
    has_any_key/2 is allowed, but Map.keys or Map.any not
    """
    def fn1(list) when has_any_key(list, [:key1, :key2]), do: :nothing
end

【问题讨论】:

标签: elixir


【解决方案1】:

让多功能头部调度“快速”是一种妥协。

守卫中允许的函数类型都具有有限的运行时间或减少计数。如果允许在警卫中使用任意函数,则必须处理在当前进程超过当前执行片之前警卫评估未完成的情况。 (或者可能更糟糕的情况是竞争条件,因为它需要来自另一个进程的输入)。

【讨论】:

  • 我已经阅读了这篇文章keathley.io/2016/04/09/elixir-guard-clauses.html,它完美地回答了我的问题,正是你所说的。守卫仅限于某些确保“纯度”且没有副作用的特定功能,例如竞争条件。
  • 不过,守卫中允许使用一种慢速功能,length/1。就像答案here 说的那样,主要原因是函数应该是纯的,应该可以忽略它们提出的错误。 Erlang/Elixir 不允许将用户定义的函数标记为 pure / ok 以忽略错误,因此您只能使用列入白名单的函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 2013-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多