我有以下声明
iex(5)> a = <<3>>
<<3>>
iex(6)> b = <<a::binary>>
<<3>>
Run Code Online (Sandbox Code Playgroud)
第一行,我创建了一个值为 3 的二进制文件。在第三行,我希望 shell 向我显示 00000011 而不是 3。我知道首先创建一个二进制文件(1.line)然后再次转换为二进制文件是没有意义的。但我期待 shell 显示 00000011 而不是 3。
当二进制像浮动一样
iex(7)> a = << 5.3 :: float >>
<<64, 21, 51, 51, 51, 51, 51, 51>>
Run Code Online (Sandbox Code Playgroud)
我不明白,为什么它显示我这个数字?
二进制是内存中的字节序列。打印的表示符合此定义。打印输出中的每个数字都在 0 到 255 之间(这些数字可以表示字节的所有可能值)。
二进制文件是解析和编码要通过网络发送到外部系统的协议或其他消息的酷而简单的方法。比如这段代码解析ip协议:
<< protocol_version :: size(4),
size_in_words :: size(4),
tos :: size(8),
total_length :: size(16),
identifier :: size(16),
flags :: size(3),
fragment_offs :: size(13),
ttl :: size(8),
protocol :: size(8),
header_checksum :: size(16),
src_ip :: size(32),
dst_ip :: size(32),
options :: size(32),
data :: binary >> = bits
Run Code Online (Sandbox Code Playgroud)
您可以匹配二进制文件的不同部分。size
以位为单位指定。最后一部分可以没有大小,但它的大小需要被 8 整除(它必须是 n 个完整字节)。
不太复杂的例子可能是数字 128,它是二进制的 10000000。
iex(1)> bin = <<128>>
<<128>>
iex(2)> <<a::size(2), b::size(6)>> = bin
<<128>>
iex(3)> a # a matched bits 10, which is 2
2
iex(4)> b # b matched bits 000000 which is 0
0
Run Code Online (Sandbox Code Playgroud)
可以使用相同的语法从部件创建二进制文件。让我们重用变量 a 和 b,但把它们放在不同的地方。
iex(5)> anotherbin = <<a::size(5), b::size(3)>>
<<16>>
Run Code Online (Sandbox Code Playgroud)
现在第一部分是 00010,第二部分是 000,它给出 00010000,即 16。另一件事是你可以从其他东西创建二进制文件,而不是像浮点数这样的整数,所以
iex(6)> a = << 5.3 :: float >>
<<64, 21, 51, 51, 51, 51, 51, 51>>
Run Code Online (Sandbox Code Playgroud)
创建另一个具有浮点值编码的二进制文件。您现在可以通过网络发送它并在另一端对其进行解码。所以和你想的相反。它不是二进制作为浮点数,而是作为二进制浮点数。
要实际查看事物的二进制表示,请尝试使用to_string
来自不同模块的方法。它们具有可选参数,该参数是您要在其中打印输出的基础。
iex(7)> Integer.to_string(128, 2)
"10000000"
Run Code Online (Sandbox Code Playgroud)
还有一个问题。Elixir 中的字符串实际上是二进制文件。shell 检查是否所有字节都是可打印字符。如果是,则将它们打印为字符串
iex(20)> <<100>>
"d"
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以强制IO.inspect
将二进制文件打印为字节或字符串列表:
iex(29)> IO.inspect <<100>>, [{:binaries, :as_binaries}]
<<100>> #this is what IO.inspect printed
"d" #this is a return value, which is the same, but printed as string
Run Code Online (Sandbox Code Playgroud)
如果您强制将不可打印的字符解释为字符串,它们将被转义:
iex(31)> IO.inspect <<2>>, [{:binaries, :as_strings}]
"\x02" #this is what IO.inspect printed
<<2>> #return value printed by shell
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
884 次 |
最近记录: |