2016-09-21 142 views
6

不知有没有什么办法可以问Elixir是否这个对象实现的协议是,类似obj |> implements(Enumerable)如何检查协议是否实现?

基本上,我必须区分结构和地图。该解决方案目前我有是有点丑:

try 
    obj |> Enum.each ... 
rescue 
    e in Protocol.UndefinedError -> obj |> Maps.keys ... 
end 

以上的作品,但我更愿意使用模式匹配,如:

cond do 
    obj |> is_implemented(Enumerable) -> ... 
    _ -> ... 
end 

我缺少的东西? 能明确检查对象是否实现了所需的协议吗?

回答

8

您可以检查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 
+1

完美,谢谢。我想知道为什么它缺少http://elixir-lang.org/docs/stable/elixir/Enumerable.html – mudasobwa

+0

可能是因为https://github.com/elixir-lang/elixir/blob/d02be44dd5deb763e5a0eb03f3c716506d781d08/lib/elixir /lib/protocol.ex#L430。 – Dogbert