2

我的空白.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 中的输出是一样的。这是否意味着这个实施什么都不做?或者我错过了什么?

4

2 回答 2

3

Any如果未提供实现,则应调用子句。

我不知道你为什么会得到这些奇怪的结果,但我怀疑你在 shell 会话中有一些不正确的定义。我已经尝试过网站上的示例

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 {}
于 2014-02-27T17:17:07.717 回答
0

我知道我的困惑是什么。我也开始使用这个网站的例子。首先我的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

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

于 2014-02-28T01:53:20.177 回答