Elixir 協(xié)議

2023-12-15 14:57 更新
  1. 協(xié)議與結(jié)構(gòu)體
  2. 執(zhí)行?Any ?
    1. 派生
    2. 回退到?Any?
  3. 內(nèi)置協(xié)議
  4. 協(xié)議鞏固

協(xié)議是Elixir中用于達到多態(tài)性的一個機制.任何數(shù)據(jù)類型只要實現(xiàn)了協(xié)議,就可以基于協(xié)議被調(diào)度.讓我們來看一個例子.

在Elixir中,只有falsenil為假.任何其他東西都為真.對應用來說,設(shè)定一個返回布爾值的blank?協(xié)議來判斷其它數(shù)據(jù)類型是否為空也許十分重要.事實上,一個空的列表或一個空的二進制數(shù)會被認為是空的.

我們能夠這樣定義協(xié)議:

defprotocol Blank do
  @doc "Returns true if data is considered blank/empty"
  def blank?(data)
end

該協(xié)議需要一個名為?blank??的函數(shù),它接受一個參數(shù).我們可以為其它Elixir數(shù)據(jù)類型實現(xiàn)這個協(xié)議:

# 整數(shù)不可能為空白
defimpl Blank, for: Integer do
  def blank?(_), do: false
end

# 空的列表是空白
defimpl Blank, for: List do
  def blank?([]), do: true
  def blank?(_),  do: false
end

# 空的映射是空白
defimpl Blank, for: Map do
  # 記住我們不能用%{}來模式匹配
  # 它能匹配所有映射.但我們可以判斷映射大小是否
  # 為零(而且計算大小是一個快速操作).
  def blank?(map), do: map_size(map) == 0
end

# 原子false和nil是空白
defimpl Blank, for: Atom do
  def blank?(false), do: true
  def blank?(nil),   do: true
  def blank?(_),     do: false
end

我們?yōu)樗性紨?shù)據(jù)類型都這樣做了.這些類型有:

Atom
BitString
Float
Function
Integer
List
Map
PID
Port
Reference
Tuple

協(xié)議和實現(xiàn)都已經(jīng)定義好,我們可以調(diào)用它了:

iex> Blank.blank?(0)
false
iex> Blank.blank?([])
true
iex> Blank.blank?([1, 2, 3])
false

傳遞了一個協(xié)議沒有實現(xiàn)的數(shù)據(jù)類型將會拋出一個錯誤:

iex> Blank.blank?("hello")
** (Protocol.UndefinedError) protocol Blank not implemented for "hello"


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號