Elixir語言中 Kernel.SpecialForms.<<args>>
相關用法介紹如下。
用法:
<<args>>
(宏)
定義一個新的位串。
例子
iex> <<1, 2, 3>>
<<1, 2, 3>>
類型
一個位串由許多段組成,每個段都有一個類型。位串中使用了 9 種類型:
integer
float
bits
(bitstring
的別名)bitstring
binary
bytes
(binary
的別名)utf8
utf16
utf32
未指定類型時,默認為 integer
:
iex> <<1, 2, 3>>
<<1, 2, 3>>
Elixir 還默認接受段為文字字符串或文字字符列表,默認情況下擴展為整數:
iex> <<0, "foo">>
<<0, 102, 111, 111>>
二進製文件需要明確標記為 binary
:
iex> rest = "oo"
iex> <<102, rest::binary>>
"foo"
utf8
、 utf16
和 utf32
類型用於 Unicode 代碼點。它們也可以應用於文字字符串和字符列表:
iex> <<"foo"::utf16>>
<<0, 102, 0, 111, 0, 111>>
iex> <<"foo"::utf32>>
<<0, 0, 0, 102, 0, 0, 0, 111, 0, 0, 0, 111>>
否則我們在構建二進製文件時會得到一個
:ArgumentError
rest = "oo"
<<102, rest>>
** (ArgumentError) argument error
選項
使用-
作為分隔符可以給出許多選項。順序是任意的,所以以下都是等價的:
<<102::integer-native, rest::binary>>
<<102::native-integer, rest::binary>>
<<102::unsigned-big-integer, rest::binary>>
<<102::unsigned-big-integer-size(8), rest::binary>>
<<102::unsigned-big-integer-8, rest::binary>>
<<102::8-integer-big-unsigned, rest::binary>>
<<102, rest::binary>>
單位和大小
匹配的長度等於unit
(位數)乘以size
(長度為unit
的重複段數)。
類型 | 默認單位 |
---|---|
integer | 1 位 |
float | 1 位 |
binary | 8 位 |
類型的大小更細微。整數的默認大小為 8。
對於浮點數,它是 64。對於浮點數,size * unit
必須產生 16、32 或 64,分別對應於 IEEE 754 binary16、binary32 和 binary64。
對於二進製文件,默認值是二進製文件的大小。隻有匹配中的最後一個二進製文件可以使用默認大小。所有其他人必須明確指定其大小,即使匹配是明確的。例如:
iex> <<name::binary-size(5), " the ", species::binary>> = <<"Frank the Walrus">>
"Frank the Walrus"
iex> {name, species}
{"Frank", "Walrus"}
大小可以是一個變量:
iex> name_size = 5
iex> <<name::binary-size(name_size), " the ", species::binary>> = <<"Frank the Walrus">>
iex> {name, species}
{"Frank", "Walrus"}
並且可以在匹配本身中定義變量(在使用之前):
iex> <<name_size::size(8), name::binary-size(name_size), " the ", species::binary>> = <<5, "Frank the Walrus">>
iex> {name, species}
{"Frank", "Walrus"}
但是,大小不能在二進製/位串匹配之外的匹配中定義:
{name_size, <<name::binary-size(name_size), _rest::binary>>} = {5, <<"Frank the Walrus">>}
** (CompileError): undefined variable "name_size" in bitstring segment
未能指定 non-last 的大小會導致編譯失敗:
<<name::binary, " the ", species::binary>> = <<"Frank the Walrus">>
** (CompileError): a binary field without size is only allowed at the end of a binary pattern
快捷方式語法
傳遞整數值時,也可以使用語法快捷方式指定大小和單位:
iex> x = 1
iex> <<x::8>> == <<x::size(8)>>
true
iex> <<x::8*4>> == <<x::size(8)-unit(4)>>
true
此語法反映了通過將大小乘以單位來給出有效大小的事實。
修飾符
某些類型具有關聯的修飾符以消除字節表示中的歧義。
修飾符 | 相關類型 |
---|---|
signed | integer |
unsigned (默認) | integer |
little | integer , float , utf16 , utf32 |
big (默認) | integer , float , utf16 , utf32 |
native | integer , utf16 , utf32 |
符號
整數可以是 signed
或 unsigned
,默認為 unsigned
。
iex> <<int::integer>> = <<-100>>
<<156>>
iex> int
156
iex> <<int::integer-signed>> = <<-100>>
<<156>>
iex> int
-100
signed
和 unsigned
僅用於匹配二進製文件(見下文)並且僅用於整數。
iex> <<-100::signed, _rest::binary>> = <<-100, "foo">>
<<156, 102, 111, 111>>
字節序
Elixir 有三個字節序選項:big
、little
和 native
。默認值為 big
:
iex> <<number::little-integer-size(16)>> = <<0, 1>>
<<0, 1>>
iex> number
256
iex> <<number::big-integer-size(16)>> = <<0, 1>>
<<0, 1>>
iex> number
1
native
由 VM 在啟動時確定,並將取決於主機操作係統。
二進製/位串匹配
二進製匹配是 Elixir 中的一項強大函數,可用於從二進製文件中提取信息以及模式匹配。
二進製匹配本身可以用來從二進製文件中提取信息:
iex> <<"Hello, ", place::binary>> = "Hello, World"
"Hello, World"
iex> place
"World"
或者作為模式匹配的函數定義的一部分:
defmodule ImageTyper do
@png_signature <<137::size(8), 80::size(8), 78::size(8), 71::size(8),
13::size(8), 10::size(8), 26::size(8), 10::size(8)>>
@jpg_signature <<255::size(8), 216::size(8)>>
def type(<<@png_signature, _rest::binary>>), do: :png
def type(<<@jpg_signature, _rest::binary>>), do: :jpg
def type(_), do: :unknown
end
性能與優化
Erlang 編譯器可以在二進製創建和匹配方麵提供許多優化。要查看優化輸出,請設置 bin_opt_info
編譯器選項:
ERL_COMPILER_OPTIONS=bin_opt_info mix compile
要了解有關特定優化和性能注意事項的更多信息,請查看Erlang 效率指南的“構建和匹配二進製文件”一章.
相關用法
- Elixir Kernel.SpecialForms.case用法及代碼示例
- Elixir Kernel.SpecialForms.%{}用法及代碼示例
- Elixir Kernel.SpecialForms.for用法及代碼示例
- Elixir Kernel.SpecialForms.quote用法及代碼示例
- Elixir Kernel.SpecialForms.require用法及代碼示例
- Elixir Kernel.SpecialForms.&expr用法及代碼示例
- Elixir Kernel.SpecialForms.{args}用法及代碼示例
- Elixir Kernel.SpecialForms.unquote_splicing用法及代碼示例
- Elixir Kernel.SpecialForms.receive用法及代碼示例
- Elixir Kernel.SpecialForms.%struct{}用法及代碼示例
- Elixir Kernel.SpecialForms.import用法及代碼示例
- Elixir Kernel.SpecialForms.left . right用法及代碼示例
- Elixir Kernel.SpecialForms.alias用法及代碼示例
- Elixir Kernel.SpecialForms.try用法及代碼示例
- Elixir Kernel.SpecialForms.fn用法及代碼示例
- Elixir Kernel.SpecialForms.cond用法及代碼示例
- Elixir Kernel.SpecialForms.__aliases__用法及代碼示例
- Elixir Kernel.SpecialForms.left :: right用法及代碼示例
- Elixir Kernel.SpecialForms.unquote用法及代碼示例
- Elixir Kernel.SpecialForms.with用法及代碼示例
- Elixir Kernel.SpecialForms.__block__用法及代碼示例
- Elixir Kernel.SpecialForms.^var用法及代碼示例
- Elixir Kernel.round用法及代碼示例
- Elixir Kernel.left / right用法及代碼示例
- Elixir Kernel.put_in用法及代碼示例
注:本文由純淨天空篩選整理自elixir-lang.org大神的英文原創作品 Kernel.SpecialForms.<<args>>。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。