“灵丹妙药”中“议定书”的意义何在?

时间:2016-10-11 09:04:42

标签: elixir

在网络(http,ftp等)中使用了术语协议,我对它在Elixir中的用法感到困惑。对于例如有对Enum模块和Enumerable Protocol的引用。 Elixir文档说Protocols are a mechanism to achieve polymorphism in Elixir

Aren他们只是一个带有一组方法/功能的模块?有什么区别吗?

1 个答案:

答案 0 :(得分:4)

将协议视为Python中Java /抽象类中的接口(实际上,java接口,特别是python抽象类更多地是@behaviour,但无论如何。)

defprotocol Sound do
  def make_sound(data)
end

defmodule Dog do
  defstruct name: "Donny"
end

defimpl Sound, for: Dog do
  def make_sound(data) do
    "#{data.name} barks “woof”"
  end
end

defmodule Cat do
  defstruct name: "Hilly"
end

defimpl Sound, for: Cat do
  def make_sound(data) do
    "#{data.name} murrs “meow”"
  end
end

并在代码中:

%Dog{} |> Sound.make_sound
#⇒ "Donny barks “woof”"

或:

pet = .... # complicated code loading a struct
pet |> Sound.make_sound # here we don’t care what pet we have

此机制用于字符串插值:

"#{5}"

上述方法有效,因为Integer具有String.Chars的实现。实现只是调用

WHATEVER_IN_#{} |> String.Chars.to_string

获取二进制文件。例如。对于前面提到的Dog模块,我们可以实现String.Chars

defimpl String.Chars, for: Dog do
  def to_string(term) do
    "#{term.name} barks “woof”"
  end
end

现在可以插入狗:

"#{%Dog{}}"
#⇒ "Donny barks “woof”"