web-dev-qa-db-ja.com

Elixirでマップの配列値を印刷する方法は?

RubyからのElixirの新機能で、次のコードを使用してマップの配列値を出力しようとしています。

map-script.ex

list = [0, 1]
map = %{0 => [1, 2], 1 => [2, 3]}

Enum.each list, fn n ->
  IO.puts map[n]
end

出力:

^A^B
^B^C

私は何を間違えていますか? ElixirはRubyに似ていますが、動作が異なります。..

29
Nona

値の内部表現を出力するには、IO.inspectの代わりにIO.putsを使用する必要があります。

iex> IO.puts [1, 2]
^A^B                          # prints "^A^B"
:ok                           # return value of IO.puts

iex> IO.inspect [1, 2]
[1, 2]                        # prints "[1, 2]"
[1, 2]                        # return value of IO.inspect

ただし、いくつかの特別な値で問題が発生する場合があります。

iex> IO.inspect [97, 98]
'ab'                          # prints "'ab'"
'ab'                          # return value of IO.inspect

この動作を説明するには、Elixirで文字列がどのように機能するかを理解する必要があります。文字列には2種類あります。バイナリ文字列(二重引用符)と文字リスト(単一引用符)。内部的には、これらはより単純なプリミティブから構築されています。バイナリ文字列はバイナリから構築され、文字リストはリストから構築されます。

iex> "ab"                    # a binary string
"ab"

iex> <<97, 98>>              # the same string in binary syntax
"ab"

iex> 'ab'                    # a character list
'ab'

iex> [97, 98]                # the same character list in list syntax
'ab'

最初は混乱しているように見えるかもしれませんが、これは2つの理由で起こります。まず、文字列は他のプリミティブ型から構築されているので、組み込みの文字列型はありません。第二に、Elixirにはユーザー定義型がありません。そのため、Elixirは整数のみのリストを見ると、便宜上それを文字列として出力しようとします。ただし、内部ではまだ整数のリストにすぎません。

上記の例では、9798は、文字abのUnicodeコードポイントを表しているため、IO.inspectを使用している場合でも文字列として表示されます。

これで、例で^A^Bが出力された理由がわかります。これらは、単に ASCII encodingからの制御文字 であり、コードポイント1および2で表されます。

ただし、このような変換を試行せずに生のリストを印刷するには、オプションchar_lists: :as_listsを渡すことができます。

iex> IO.inspect [97, 98], char_lists: :as_lists
[97, 98]                                         # prints '[97, 98]'
'ab'                                             # Iex still shows the return value as 'ab'

iexを開いてh Inspect.Optsと入力すると、Elixirが他の値、特に構造体とバイナリに対してこの種の処理を行うことがわかります。

64
Patrick Oscity