Elixir`dedexropocol`中的“Any”实际上包含什么?

时间:2014-02-27 13:58:11

标签: elixir

我的 blank.ex 是:

defprotocol Blank do
  @fallback_to_any true
  def blank?(data)
end

defimpl Blank, for: Any do
  def blank?(_), do: false
end

我键入iex,输出为:

iex(18)> Blank.blank? []
true
iex(19)> Blank.blank? [6]
false
iex(20)> Blank.blank? '12'
false
iex(22)> Blank.blank? "' "
true
iex(23)> Blank.blank? "elixi"
true
iex(24)> Blank.blank? {1}
true
iex(25)> Blank.blank? {1, 2}
true
iex(26)> Blank.blank? 2
false

所以我想知道Any在这种情况下意味着什么?我得到了一些有趣的东西,天气与否,我使用像这样的实施

defimpl Blank, for: Any do
  def blank?(_), do: false
end

和iex之前的输出相同。这是否意味着这实施无效?或者我错过了什么?

2 个答案:

答案 0 :(得分:3)

如果未提供实现,则应调用

Any子句。

我不知道为什么你会得到这些奇怪的结果,但我怀疑你在shell会话中有一些不正确的定义。我尝试过example from the site

defprotocol Blank do
  @fallback_to_any true
  def blank?(data)
end

defimpl Blank, for: Integer do
  def blank?(_), do: false
end

# Just empty list is blank
defimpl Blank, for: List do
  def blank?([]), do: true
  def blank?(_),  do: false
end

# Just the atoms false and nil are blank
defimpl Blank, for: Atom do
  def blank?(false), do: true
  def blank?(nil),   do: true
  def blank?(_),     do: false
end

defimpl Blank, for: Any do
  def blank?(_), do: false
end

得到了预期的结果:

iex(1)> Blank.blank? "' "
false

iex(2)> Blank.blank? "elixi"
false

iex(3)> Blank.blank? []
true

iex(4)> Blank.blank? {}  # fallback to Any
false

最后一个示例是Any的回退,因为没有为元组定义协议。如果删除Any实施,重新启动 shell,则会出错:

iex(1)> Blank.blank? {}
** (Protocol.UndefinedError) protocol Blank not implemented for {}

答案 1 :(得分:0)

我知道我的困惑是什么。我也开始使用example this site。首先我的 blank.ex

defprotocol Blank do
  def blank?(data)
end

defimpl Blank, for: Integer do
  def blank?(_), do: false
end

defimpl Blank, for: List do
  def blank?([]), do: true
  def blank?(_), do: false
end

在我编译elixirc blank.ex之后,它将创建这些光束文件:

Elixir.Blank.Integer.beam   Elixir.Blank.List.beam   Elixir.Blank.beam

其次我的 blank.ex

defprotocol Blank do
  @fallback_to_any true
  def blank?(data)
end

defimpl Blank, for: Any do
  def blank?(_), do: true
end

我再次编译它,我得到了这些光束文件:

Elixir.Blank.Any.beam  Elixir.Blank.Integer.beam Elixir.Blank.List.beam Elixir.Blank.beam

它不会删除Elixir.Blank.Integer.beam Elixir.Blank.List.beam文件,当我在iex中运行时

iex(18)> Blank.blank? [] # it uses Elixir.Blank.List.beam
true
iex(19)> Blank.blank? [6] # it uses Elixir.Blank.List.beam
false
iex(20)> Blank.blank? '12' # it uses Elixir.Blank.List.beam
false
iex(22)> Blank.blank? "' " # it uses Elixir.Blank.Any.beam
true
iex(23)> Blank.blank? "elixi" # it uses Elixir.Any.List.beam
true
iex(24)> Blank.blank? {1} # it uses Elixir.Blank.Any.beam
true
iex(25)> Blank.blank? {1, 2} # it uses Elixir.Blank.Any.beam
true
iex(26)> Blank.blank? 2 # it uses Elixir.Blank.Integer.beam
false

所以这只是因为我没有手动删除旧的光束文件。