當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Elixir Kernel.SpecialForms.<<args>>用法及代碼示例


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"

utf8utf16utf32 類型用於 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的重複段數)。

類型默認單位
integer1 位
float1 位
binary8 位

類型的大小更細微。整數的默認大小為 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

此語法反映了通過將大小乘以單位來給出有效大小的事實。

修飾符

某些類型具有關聯的修飾符以消除字節表示中的歧義。

修飾符相關類型
signedinteger
unsigned(默認)integer
littleinteger , float , utf16 , utf32
big(默認)integer , float , utf16 , utf32
nativeinteger , utf16 , utf32

符號

整數可以是 signedunsigned ,默認為 unsigned

iex> <<int::integer>> = <<-100>>
<<156>>
iex> int
156
iex> <<int::integer-signed>> = <<-100>>
<<156>>
iex> int
-100

signedunsigned 僅用於匹配二進製文件(見下文)並且僅用於整數。

iex> <<-100::signed, _rest::binary>> = <<-100, "foo">>
<<156, 102, 111, 111>>

字節序

Elixir 有三個字節序選項:biglittlenative。默認值為 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-lang.org大神的英文原創作品 Kernel.SpecialForms.<<args>>。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。