本 EEP 描述了將位元級二進制數據引入 Erlang 程式語言的過程。它們可以使用位元語法和一組新的 BIF 來構建和操作,這些 BIF 操作位元級二進制數據。引入這些新的 BIF 是為了不改變現有操作二進制數據的 BIF 的語義,而是使用新的 BIF 來實現類似的位元級二進制數據操作。
本文檔中稱為位元字串的位元級二進制數據是任意長度的位元序列。另一方面,二進制數據是一個位元序列,其中位元數可以被 8 整除。這些定義意味著任何二進制數據也是位元字串。
位元語法表達式
<<Seg1,...,SegN>>
評估為位元字串,如果表達式中所有區段的大小總和可以被 8 整除,則結果也是二進制數據。以前,此類表達式只能評估為二進制數據,如果不是這種情況,則會引發運行時錯誤。
透過此擴展,先前導致運行時錯誤的表達式 Bin = <<1:9>>
現在會建立一個 9 位元的二進制數據。為了能夠使用這個位元字串來建立一個新的更大的位元字串,我們可以寫成
<<Bin/bitstring, 0:1>>
請注意使用 bitstring 作為類型。這會擴展為 binary-unit:1,而 binary 類型會擴展為 binary-unit:8。由於 bitstring 在二進制模式中是一個很長的單字,因此有一個別名 bits,它將在本提案的其餘部分中使用,類似地,binary 也有一個簡寫 bytes。
為了比對出位元級二進制數據,我們也使用位元字串類型,如下所示:
case Bin of
<<1:1,Rest/bits>> -> Rest;
<<0:1,_/bits>> -> 0
end
這使我們能夠避免必須計算填充的情況。
bitsize/1::bitstring() -> integer()
傳回位元字串的大小(以位元為單位)。此 BIF 允許在 guards 中使用。
list_to_bitstring/1::bitstring_list() -> bitstr()
bitstring_list = cons(char() | bitstring()| bitstring_list(), bitstring() | bitstring_list) | nil()
將 bitstring_list 中的位元字串和字元串連起來以建立位元字串,每個字元變成一個 8 位元的位元字串。
is_bitstring/1::any() -> bool()
如果引數是位元字串,則傳回 true,否則傳回 false。此 BIF 允許在 guards 中使用。
bitstring_to_list/1::bitstring() -> [char()|bitstring()]
將位元字串轉換為字元列表,如果位元字串中的位元數不能被 8 整除,則列表中的最後一個元素是位元字串,其中包含原始位元字串的最後 1-7 位元。
目前二進制數據的定義使得當格式不是以位元組為導向時,使用位元語法進行解碼變得複雜,因為程式設計人員總是會被迫填充他正在使用的二進制數據,使其成為位元組序列。允許位元級二進制數據可以減輕這個問題。
此處提出的新 BIF 旨在為程式設計人員提供與操作二進制數據時相同的工具來操作位元級二進制數據,而不會更改現有 BIF 的語義,並保持以下語句的屬性:
is_binary(X) andalso size(X) =:= 0
評估結果為 true,則表示 X = <<>>
。
本文檔中描述的擴展程式碼已在 R11B-4 中實作,但受編譯器開關保護,或者可以輕鬆實作。
此變更不會完全向後相容,例如:N=9, <<1:N>>
在舊系統中會導致錯誤,現在它會評估為位元字串。
新的 BIF 旨在為處理位元級二進制數據提供與處理普通二進制數據相同的表達能力,而不會更改二進制數據的 BIF(例如 size/1、binary_to_list/1、list_to_binary/1 等)的語義。這表示如果其引數包含位元字串,則所有此類 BIF 都會擲回例外。