Char列出了代码点原子

zer*_*ing 1 elixir

当我在iex中写这个

iex> 'he??o'  
Run Code Online (Sandbox Code Playgroud)

它向我展示了代码点

[104, 101, 322, 322, 111]  
Run Code Online (Sandbox Code Playgroud)

我知道因为单引号字符串代表char列表.但是当我在iex中输入带有上述数字的列表时,它会显示一个带有数字的列表,而不是hełło

iex(13)> [104, 101, 322, 322, 111] 
[104, 101, 322, 322, 111]
Run Code Online (Sandbox Code Playgroud)

为什么它没有给我看人物?
当我输入

iex(3)> a = [67,55,44]
Run Code Online (Sandbox Code Playgroud)

进入iex,我有以下角色

'C7,'
Run Code Online (Sandbox Code Playgroud)

什么,当我想要iex显示数字而不是字符?
为什么我可以在这里传递一个原子作为arity?

iex> to_string :hello
"hello"
Run Code Online (Sandbox Code Playgroud)

Pat*_*ity 6

当您检查列表(或查看iex中的返回值)时,Elixir将检查列表是否仅包含有效的代码点.如果是这种情况,它将以字符串表示形式打印列表,否则将打印为列表.字符列表也只是整数列表,因此相同的规则适用于那些.观察其中一些示例,看看char列表实际上只是列表:

# '' for example is the same as an empty list []
iex> ''
[]

# a char list with valid codepoints will be printed as string
iex> 'A'
'A'

# a char list with invalid codepoints will be printed as list
iex> 'A' ++ [0]
[65, 0]

# a list with only valid codepoints will also be printed as string
iex> [65]
'A'
Run Code Online (Sandbox Code Playgroud)

这意味着char列表没什么特别的,只是整数列表.现在碰巧char列表无法处理UTF8字符.它们主要用于Erlang互操作性,因为我们需要一种方法来回转换"Erlang字符串".如果我没弄错的话,Erlang也不知道如何在char列表中处理UTF8,因此可能出于历史原因以这种方式实现.

但是,Elixir足以将char列表文字中的UTF8字符转换为适当的代码点,因此您可以稍后将其转换为二进制文件并获取正确的UTF8字符:

# UTF8 codepoints are not valid for char lists
iex> 'he??o'
[104, 101, 322, 322, 111]

# however you can convert a list with UTF8 codepoints to a binary
iex> to_string('he??o')
"he??o"
Run Code Online (Sandbox Code Playgroud)

Iex在内部使用inspect协议来打印返回值.但是,如果您手动调用inspect,则可以传递其他选项.例如,要查看char列表的代码点:

iex> IO.puts inspect('hello', char_lists: false)
[104, 101, 108, 108, 111]
:ok
Run Code Online (Sandbox Code Playgroud)

如果你想看到二进制代码点:

iex> IO.puts inspect("hello", binaries: :as_binaries)
<<104, 101, 108, 108, 111>>
:ok
Run Code Online (Sandbox Code Playgroud)

如需更多选项,请h Inspect.Opts登入iex.这种技术使我们能够清楚地看到char列表和二进制文件中UTF8代码点之间的区别.区别在于char列表将一个字符表示为一个整数,而二进制文件将UTF8代码点正确存储为多个字节:

iex> IO.puts inspect('?', char_lists: false)
[322]
:ok

iex> IO.puts inspect("?", binaries: :as_binaries)
<<197, 130>>
:ok
Run Code Online (Sandbox Code Playgroud)

也就是说,如果你呆在Elixir中,你应该真的,真的使用二进制代替char列表.Char列表通常仅用于与使用它们的Erlang代码进行交互.

  • 对于我认为只是ASCII字符集的char列表. (2认同)