Elixir 协议
2023-12-15 14:57 更新
- 协议与结构体
- 执行
Any
- 派生
- 回退到
Any
- 内置协议
- 协议巩固
协议是Elixir中用于达到多态性的一个机制.任何数据类型只要实现了协议,就可以基于协议被调度.让我们来看一个例子.
在Elixir中,只有false
和nil
为假.任何其他东西都为真.对应用来说,设定一个返回布尔值的blank?
协议来判断其它数据类型是否为空也许十分重要.事实上,一个空的列表或一个空的二进制数会被认为是空的.
我们能够这样定义协议:
defprotocol Blank do
@doc "Returns true if data is considered blank/empty"
def blank?(data)
end
该协议需要一个名为blank?
的函数,它接受一个参数.我们可以为其它Elixir数据类型实现这个协议:
# 整数不可能为空白
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
我们为所有原始数据类型都这样做了.这些类型有:
Atom
BitString
Float
Function
Integer
List
Map
PID
Port
Reference
Tuple
协议和实现都已经定义好,我们可以调用它了:
iex> Blank.blank?(0)
false
iex> Blank.blank?([])
true
iex> Blank.blank?([1, 2, 3])
false
传递了一个协议没有实现的数据类型将会抛出一个错误:
iex> Blank.blank?("hello")
** (Protocol.UndefinedError) protocol Blank not implemented for "hello"
以上内容是否对您有帮助:
更多建议: