Elixir - 協議



協議是Elixir中實現多型性的機制。只要資料型別實現了協議,就可以對其進行協議分發。

讓我們考慮一個使用協議的例子。在前面的章節中,我們使用了一個名為`to_string`的函式來將其他型別轉換為字串型別。這實際上是一個協議。它根據給定的輸入進行操作,不會產生錯誤。這看起來像是我們正在討論模式匹配函式,但隨著我們的深入,情況會變得不同。

考慮以下示例以進一步瞭解協議機制。

讓我們建立一個協議來顯示給定的輸入是否為空。我們將此協議稱為`blank?`。

定義協議

我們可以在Elixir中透過以下方式定義協議:

defprotocol Blank do
   def blank?(data)
end

正如你所看到的,我們不需要為函式定義函式體。如果你熟悉其他程式語言中的介面,你可以將協議視為本質上相同的東西。

因此,這個協議表明,任何實現它的東西都必須具有`empty?`函式,儘管實現者如何響應該函式取決於實現者。在定義了協議之後,讓我們瞭解如何新增幾個實現。

實現協議

由於我們已經定義了一個協議,我們現在需要告訴它如何處理它可能接收到的不同輸入。讓我們基於我們之前使用的示例進行構建。我們將為列表、對映和字串實現`blank`協議。這將顯示我們傳遞的內容是否為空。

#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

**注意** - 如果你將其用於你未為其定義協議的任何型別,它將產生錯誤。

廣告