Bạn nên sử dụng IO.inspect
thay vì IO.puts
để in các đại diện nội bộ của một giá trị:
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
Tuy nhiên bạn vẫn có thể nhận được vấn đề với một số giá trị đặc biệt :
iex> IO.inspect [97, 98]
'ab' # prints "'ab'"
'ab' # return value of IO.inspect
Để giải thích hành vi này, chúng tôi cần hiểu cách thức hoạt động của chuỗi trong Elixir. Có hai loại dây. Các chuỗi nhị phân (được trích dẫn kép) và các danh sách ký tự (được trích dẫn một lần). Nội bộ, chúng được xây dựng từ nguyên thủy đơn giản hơn. Chuỗi nhị phân được tạo từ tệp nhị phân và danh sách ký tự được tạo từ danh sách:
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'
Ban đầu có vẻ khó hiểu nhưng điều này xảy ra do hai điều. Đầu tiên, không có kiểu chuỗi được tạo sẵn, vì chúng ta đã thấy các chuỗi được tạo từ các kiểu nguyên thủy khác. Thứ hai, không có loại người dùng nào được xác định trong Elixir. Vì vậy, khi Elixir nhìn thấy một danh sách chỉ với số nguyên, nó cố gắng in nó như một chuỗi để thuận tiện. Tuy nhiên, dưới mui xe nó vẫn chỉ là một danh sách các số nguyên.
Trong ví dụ trên, 97
và 98
đại diện cho các điểm mã unicode cho các nhân vật a
và b
do đó, những sẽ được hiển thị như là một chuỗi, thậm chí nếu sử dụng IO.inspect
.
Bây giờ bạn có thể thấy lý do tại sao nó được in ^A^B
trong ví dụ của bạn - đây là những chỉ control characters from the ASCII encoding, lề diễn ra được đại diện bởi các codepoints 1
và 2
.
Tuy nhiên, bạn có thể vượt qua các tùy chọn char_lists: :as_lists
để in danh sách nguyên liệu mà không có một nỗ lực để làm một sự chuyển đổi như:
iex> IO.inspect [97, 98], char_lists: :as_lists
[97, 98] # prints '[97, 98]'
'ab' # Iex still shows the return value as 'ab'
Nếu bạn mở iex
và gõ h Inspect.Opts
, bạn sẽ thấy rằng Elixir thực hiện điều này loại điều với các giá trị khác là tốt, cụ thể cấu trúc và nhị phân.
Đó là một sai lầm lớn khi cho rằng vì Elixir trông giống như Ruby, nó sẽ hoạt động giống như Ruby. –