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に似ていますが、動作が異なります。..
値の内部表現を出力するには、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は整数のみのリストを見ると、便宜上それを文字列として出力しようとします。ただし、内部ではまだ整数のリストにすぎません。
上記の例では、97
と98
は、文字a
とb
の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が他の値、特に構造体とバイナリに対してこの種の処理を行うことがわかります。