问题
In Elixir, why does the comprehension for x <- 3..4, do: x * 2
result in [6, 8]
but for x <- 3..4, do: x * 3
results in '\t\f'
?
I'm executing this in the iex
repl.
回答1:
This is one of the most confusing gotchas in Elixir: the "humanizing" of charlists. See this post for a question revolving around this same issue.
Charlists are lists of integer codepoints, used to represent un-encoded strings (more common in older Erlang libraries from the days before encodings were baked in). So if you have a list of integers, Elixir (for historical reasons), has to guess whether or not you meant to represent a 'string' -- so if all the integers in that list are below 127, Elixir assumes that this must be a charlist that represents 'string' data and it prints out the corresponding ASCII characters to make a readable string.
You can reveal the actual inner representation by setting the charlists: :as_lists
option in your calls to IO.inspect/2
:
iex(1)> result = for x <- 3..4, do: x * 3
'\t\f'
iex(2)> IO.inspect(result, charlists: :as_lists)
[9, 12]
'\t\f'
or more simply:
iex> IO.inspect([9, 12], charlists: :as_lists)
[9, 12]
'\t\f'
This shows us the expected integers (9, 12), and if we bother to look these up in a Unicode or ASCII code chart, we would see that the \t
and \f
characters are represented by codepoints 9 and 12 respectively.
Keep in mind that these representations of the data are just visual -- the underlying data is 100% the same:
iex> [9, 12] === '\t\f'
true
来源:https://stackoverflow.com/questions/65135280/why-does-for-x-3-4-do-x-3-return-t-f-in-elixir