【问题标题】:Elixir pattern match protocol implementorElixir 模式匹配协议实现者
【发布时间】:2018-01-03 18:05:09
【问题描述】:

您可以在方法中对特定结构进行模式匹配,以防止某些类型错误的泄漏。例如。 def f(z_struct = %Z{}) do ...

如果你不知道结构的类型,你能做类似的事情吗?比如说,如果你想要一个实现协议P的模块的结构。?

defprotocol P do
  # ...
end

defmodule A do
  defstruct :a
end
defimpl P, for: A do
  # ...
end

defmodule B do
  defstruct :b
end
defimpl P, for: B do
  # ...
end

defmodule SomeMod do
  def m(p) do
    # ...
  end
end

即方法 SomeMod.m/1 应该只接受 %A{} 或 %B{} 作为参数。如果模块C 稍后实现Pm/1 应该接受C 而无需更改代码。

我们可以做这个灵药吗?


如果上面的解释不好,可以把它想象成在Java中接受一个接口,其中P是接口,AB是实现P的类。

【问题讨论】:

    标签: pattern-matching elixir protocols


    【解决方案1】:

    在函数子句中使用守卫/模式匹配是不可能的。断言这一点的唯一方法是使用反射Kernel.impl_for/1

    defmodule SomeMod do
      def m(p) do
        unless P.impl_for(p), do: raise MatchError, term: p
        # ...
      end
    end
    

    【讨论】:

    • 我什至有一篇关于这个主题的博文:this would be another approach to pattern match protocols
    • 有趣的文章。我们不能使用宏作为impl_for 函数的包装器,以便我们可以在守卫中使用它吗?这意味着我们必须编写require ModuleContainingTheMacro,这有点烦人,但它需要的代码更少。它也将被限制为单个参数
    • 我不确定我是否遵循。我们一开始就不能在守卫中使用impl_for
    猜你喜欢
    • 2017-07-01
    • 2017-04-19
    • 2017-11-03
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多