如何检查协议是否已实现?

Ale*_*kin 10 elixir

我想知道是否有任何方法可以问Elixir 这个对象是否实现了该协议,类似于obj |> implements(Enumerable)什么?

基本上,我必须区分结构和地图.我目前的解决方案有点难看:

try
  obj |> Enum.each ...
rescue 
  e in Protocol.UndefinedError -> obj |> Maps.keys ...
end
Run Code Online (Sandbox Code Playgroud)

上面的工作,但我更喜欢使用模式匹配,如:

cond do
  obj |> is_implemented(Enumerable) -> ...
  _ -> ...
end
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?可以明确检查对象是否实现了所需的协议?

Dog*_*ert 11

您可以检查Protocol.impl_for(term)返回是否为零:

iex(1)> Enumerable.impl_for []
Enumerable.List
iex(2)> Enumerable.impl_for {}
nil
iex(3)> Enumerable.impl_for MapSet.new
Enumerable.MapSet
Run Code Online (Sandbox Code Playgroud)

  • 很好,谢谢。我想知道为什么它在 http://elixir-lang.org/docs/stable/elixir/Enumerable.html 中丢失 (3认同)