Trabalhar com dados binários pode ser complicado, então o Gleam oferece um tipo BitArray e uma sintaxe própria para construir e fazer casamento de padrões com dados binários.
Os literais de array de bits são definidos com a sintaxe <<>>. Ao definir um literal de array de bits, ele é dividido em segmentos. Cada segmento tem um valor e uma anotação, separados por :. A anotação especifica quantos bits serão usados para codificar o valor e pode ser omitida por completo, o que assume o padrão de um valor inteiro 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 o tipo como :1 é uma forma abreviada de escrever :size(1). Você precisa usar a sintaxe mais longa se o tamanho em bits vier de uma variável.
let segment_size = 1
<<0:size(segment_size), 1:size(segment_size), 0:size(segment_size)>>
Ao escrever literais inteiros binários, podemos escrevê-los diretamente em notação de base 2, prefixando o literal com 0b. Repare que eles serão exibidos como números decimais quando forem impressos nos testes ou no seu programa.
<<0b1011:4>> == <<11:4>>
// -> True
Se o valor do segmento ultrapassar a capacidade do tipo do segmento, ele será truncado pela esquerda.
<<0b1011:3>> == <<0b0011:3>>
// -> True
Você pode adicionar elementos tanto no início quanto no final de um array de bits existente usando a sintaxe de array de bits. A anotação :bits deve ser usada para o array de bits existente.
let value = <<0b110:3, 0b001:3>>
let new_value = <<0b011:3, value:bits, 0b000:3>>
// -> <<120, 8:size(4)>>
Podemos concatenar arrays de bits guardados em variáveis usando a sintaxe. A anotação :bits deve ser usada ao concatenar dois arrays de bits de tamanhos variáveis.
let first = <<0b110:3>>
let second = <<0b001:3>>
let concatenated = <<first:bits, second:bits>>
// -> <<49:size(6)>>
Também é possível fazer casamento de padrões para obter valores do array de bits. Você precisa saber o número de bits de cada fragmento que quer capturar, com uma exceção: a anotação :bits pode ser usada para fazer casamento de padrões em um array de bits de tamanho desconhecido, mas isso só funciona no último fragmento.
let assert <<value:4, rest:bits>> = <<0b01101001:8>>
value == 0b0110
// -> true
Os arrays de bits podem ser impressos em um formato diferente do formato que foi usado para criá-los. Isso costuma causar confusão quando se está aprendendo arrays de bits.
Por padrão, os arrays de bits são exibidos em fragmentos de 8 bits (um byte), mesmo que você os tenha criado com fragmentos de outro tamanho.
<<2011:11>>
// -> <<251, 3:size(3)>>
Se você criar um array de bits que representa uma string imprimível codificada em UTF-8, ele pode ser exibido como uma string usando a echo keyword quando o alvo é o Erlang. Isso acontece por causa de um detalhe de implementação de como o Gleam representa strings internamente.
<<>>
// -> ""
<<65, 66, 67>>
// -> "ABC"