/ / Elixir `defprotocol`の` Any`には実際に何が含まれていますか? -エリキシル

エリクシル `defprotocol`の` Any`は実際に何を含んでいますか? - エリキシル

じぶんの 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の出力は同じです。これは、これが実装されていることは何も意味しないのか、それとも何かを見落としているのでしょうか?

回答:

回答№1の場合は3

Any 実装が提供されていない場合は、句を呼び出す必要があります。

これらの奇妙な結果が得られているのは「なぜあなたにはわからない」のですが、シェルセッションに誤った定義があると思われます。私は試しました サイトからの例

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 実装、および 再起動 シェルでは、エラーが発生するはずです。

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

回答№2の場合は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

これは、古いビームファイルを手動で削除することができないためです。