Trabajar con datos binarios puede ser complicado, así que Gleam ofrece un tipo BitArray y una sintaxis que lo acompaña para construir datos binarios y hacer coincidencia de patrones con ellos.
Los literales de bit array se definen con la sintaxis <<>>. Cuando defines un literal de bit array, este se define en segmentos. Cada segmento tiene un valor y una anotación, separados por :. La anotación especifica cuántos bits se usarán para codificar el valor, y puede omitirse por completo, en cuyo caso el valor predeterminado será un entero de 8 bits.
// 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>>
Especificar el tipo como :1 es una forma abreviada de escribir :size(1). Necesitas usar la sintaxis más larga si el tamaño de bits proviene de una variable.
let segment_size = 1
<<0:size(segment_size), 1:size(segment_size), 0:size(segment_size)>>
Cuando escribes literales enteros binarios, puedes escribirlos directamente en notación de base 2 si antepones 0b al literal. Ten en cuenta que se mostrarán como números decimales cuando se impriman en las pruebas o en tu programa.
<<0b1011:4>> == <<11:4>>
// -> True
Si el valor del segmento sobrepasa la capacidad del tipo del segmento, se truncará por la izquierda.
<<0b1011:3>> == <<0b0011:3>>
// -> True
Puedes tanto anteponer como agregar al final de un bit array existente usando la sintaxis de bit arrays. La anotación :bits debe usarse para el bit array existente.
let value = <<0b110:3, 0b001:3>>
let new_value = <<0b011:3, value:bits, 0b000:3>>
// -> <<120, 8:size(4)>>
Podemos concatenar bit arrays guardados en variables usando la sintaxis. La anotación :bits debe usarse cuando concatenas dos bit arrays de tamaños variables.
let first = <<0b110:3>>
let second = <<0b001:3>>
let concatenated = <<first:bits, second:bits>>
// -> <<49:size(6)>>
También puedes hacer coincidencia de patrones para obtener valores del bit array. Debes saber la cantidad de bits de cada fragmento que quieras capturar, con una excepción: la anotación :bits se puede usar para hacer coincidencia de patrones sobre un bit array de tamaño desconocido, pero solo se puede usar para el último fragmento.
let assert <<value:4, rest:bits>> = <<0b01101001:8>>
value == 0b0110
// -> true
Puede que los bit arrays se impriman en un formato distinto del que usaste para crearlos. Esto suele causar confusión cuando se aprenden los bit arrays.
De forma predeterminada, los bit arrays se muestran en fragmentos de 8 bits (un byte), incluso si los creaste con fragmentos de otro tamaño.
<<2011:11>>
// -> <<251, 3:size(3)>>
Si creas un bit array que representa un string imprimible codificado en UTF-8, puede que se muestre como un string usando la echo keyword cuando el objetivo es Erlang. Esto se debe a un detalle de implementación de cómo Gleam representa los strings de forma interna.
<<>>
// -> ""
<<65, 66, 67>>
// -> "ABC"