【问题标题】:What does `Any` in Elixir `defprotocol` actually contains?Elixir `defprotocol` 中的 `Any` 实际上包含什么?
【发布时间】:2014-02-28 09:53:20
【问题描述】:

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

【问题讨论】:

    标签: elixir


    【解决方案1】:

    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 {}
    

    【讨论】:

      【解决方案2】:

      我知道我的困惑是什么。我也开始使用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
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-04
        • 1970-01-01
        • 2020-01-02
        • 2010-11-12
        • 2016-01-25
        • 2017-09-01
        • 1970-01-01
        相关资源
        最近更新 更多