📅  最后修改于: 2020-11-04 08:28:49             🧑  作者: Mango
协议是在Elixir中实现多态的机制。只要协议实现协议,就可以对任何数据类型进行调度。
让我们考虑一个使用协议的例子。在前面的章节中,我们使用了一个名为to_string的函数将其他类型转换为字符串类型。这实际上是一个协议。它根据给出的输入进行操作而不会产生错误。似乎我们正在讨论模式匹配功能,但是随着我们进一步进行,结果却有所不同。
考虑以下示例,以进一步了解协议机制。
让我们创建一个协议,该协议将在给定输入是否为空时显示。我们将这个协议称为空白吗? 。
我们可以通过以下方式在Elixir中定义协议-
defprotocol Blank do
def blank?(data)
end
如您所见,我们不需要为函数定义主体。如果您熟悉其他编程语言中的接口,则可以认为协议本质上是同一件事。
因此,该协议说,实现该协议的任何内容都必须为空?函数,尽管函数的响应方式取决于实现者。定义好协议后,让我们了解如何添加几个实现。
由于已经定义了协议,因此现在我们需要告诉它如何处理它可能得到的不同输入。让我们以前面的示例为基础。我们将为列表,映射和字符串实现空白协议。这将显示我们传递的内容是否为空白。
#Defining the protocol
defprotocol Blank do
def blank?(data)
end
#Implementing the protocol for lists
defimpl Blank, for: List do
def blank?([]), do: true
def blank?(_), do: false
end
#Implementing the protocol for strings
defimpl Blank, for: BitString do
def blank?(""), do: true
def blank?(_), do: false
end
#Implementing the protocol for maps
defimpl Blank, for: Map do
def blank?(map), do: map_size(map) == 0
end
IO.puts(Blank.blank? [])
IO.puts(Blank.blank? [:true, "Hello"])
IO.puts(Blank.blank? "")
IO.puts(Blank.blank? "Hi")
您可以根据需要使用任意数量的类型来实现协议,无论使用哪种协议都有意义。这是协议的一个非常基本的用例。运行上述程序时,将产生以下结果-
true
false
true
false
注意-如果将其用于定义协议的类型以外的其他类型,则会产生错误。