Робота з двійковими даними може бути непростою, тож Gleam надає тип BitArray і відповідний синтаксис, щоб створювати бітові масиви та зіставляти їх зі зразком.
Літерали бітових масивів визначаються за допомогою синтаксису <<>>. Коли ми визначаємо літерал бітового масиву, він складається з сегментів. Кожен сегмент має значення й анотацію, розділені символом :. Анотація вказує, скільки бітів буде використано для кодування значення, і її можна повністю опустити; тоді типовим буде 8-бітове ціле число.
// This defines a bit array with three segments of a single bit each
<<0:1, 1:1, 0:1>>
// This defines a bit array with three segments of 8 bits each
<<0, 1, 0>>
Запис типу як :1 скорочує запис :size(1). Якщо розмір у бітах походить із змінної, потрібно використати довший синтаксис.
let segment_size = 1
<<0:size(segment_size), 1:size(segment_size), 0:size(segment_size)>>
Коли ми записуємо двійкові літерали цілих чисел, ми можемо писати їх безпосередньо в двійковій системі числення, додавши на початок літерала 0b. Зауважмо, що в тестах чи в нашій програмі вони відображатимуться як десяткові числа.
<<0b1011:4>> == <<11:4>>
// -> True
Якщо значення сегмента перевищує місткість типу сегмента, його буде обрізано зліва.
<<0b1011:3>> == <<0b0011:3>>
// -> True
Ми можемо додавати як на початок, так і в кінець наявного бітового масиву, використовуючи синтаксис бітових масивів. Для наявного бітового масиву потрібно використати анотацію :bits.
let value = <<0b110:3, 0b001:3>>
let new_value = <<0b011:3, value:bits, 0b000:3>>
// -> <<120, 8:size(4)>>
Ми можемо зʼєднувати бітові масиви, збережені у змінних, за допомогою цього синтаксису. Анотацію :bits потрібно використати, коли ми зʼєднуємо два бітові масиви змінного розміру.
let first = <<0b110:3>>
let second = <<0b001:3>>
let concatenated = <<first:bits, second:bits>>
// -> <<49:size(6)>>
Зіставлення зі зразком також можна застосовувати, щоб отримати значення з бітового масиву. Потрібно знати кількість бітів для кожного фрагмента, який ми хочемо захопити, за одним винятком: анотацію :bits можна використати, щоб зіставити зі зразком бітовий масив невідомого розміру, але це можливо лише для останнього фрагмента.
let assert <<value:4, rest:bits>> = <<0b01101001:8>>
value == 0b0110
// -> true
Бітові масиви можуть друкуватися у форматі, відмінному від того, який використовувався для їх створення. Це часто спантеличує тих, хто вивчає бітові масиви.
Типово бітові масиви відображаються фрагментами по 8 бітів (один байт), навіть якщо ми створили їх із фрагментів іншого розміру.
<<2011:11>>
// -> <<251, 3:size(3)>>
Якщо ми створимо бітовий масив, який представляє придатний для друку рядок тексту (англ. string) у кодуванні UTF-8, він може відобразитися як рядок тексту за допомогою echo keyword, коли цільовою платформою виступає Erlang. Це повʼязано з деталлю реалізації того, як Gleam внутрішньо представляє рядки тексту.
<<>>
// -> ""
<<65, 66, 67>>
// -> "ABC"