Здравствуйте, я пытался понять, как работать с двоичными файлами в Эликсире, и я пытался разобрать строку
"2018-04-07 13:00:00.000000"
Я хотел получить их часть года и сделал следующее
date = "2018-04-07 13:00:00.000000"
<< d::size(80), rest::binary >> = date
Теперь, когда я пытаюсь отдохнуть, я получаю все после свидания, включая пробел
" 13:00:00.000000"
Но если я пытаюсь получить d, я действительно не понимаю, что получаю, но результат следующий
237007314493411930484791
Не могли бы вы, ребята, помочь понять, что происходит.
Спасибо.
2 ответа
Решение вашей проблемы - использовать binary-size
следующим образом: << d::binary-size(10), rest::binary >> = date
После выдержки из документации следует уточнить соответственно:
Битовая строка состоит из множества сегментов, и каждый сегмент имеет тип. В битовых строках используются 9 типов: -
integer
-float
-bits
(псевдоним дляbitstring
) -bitstring
-binary
-bytes
(псевдоним дляbinary
) -utf8
-utf16
-utf32
Если тип не указан, по умолчанию используетсяinteger
Например, << d::integer-size(80), rest::binary >> = date
дал бы вам тот же результат, что и вы сообщили.
Хотя ответ Кевина Джонсона прекрасно объясняет, как обращаться с двоичными файлами, я опубликую объяснение того, что произошло на самом деле.
Бинарный файл в Erlang (и, следовательно, в Elixir) может быть создан с использованием значений ASCII для символов:
iex|1 ▶ <<50, 48>>
#⇒ "20"
Когда вы сопоставляете образец с size(80)
, вы фактически сопоставляете образец с 10 позициями целого числа в 256-основном. По сути, произошло вот что:
iex|2 ▶ <<a1::size(8), a2::size(8), a3::size(8),
a4::size(8), a5::size(8), a6::size(8),
a7::size(8), a8::size(8), a9::size(8),
a10::size(8), _ :: binary>> = "2018-04-07 13..."
#⇒ "2018-04-07 13..."
Давайте проверим наши значения (да, массив целых чисел по возможности распечатывается как битовая строка, обратите внимание на одинарные кавычки ):
iex|3 ▶ [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]
#⇒ '2018-04-07'
Хорошо, пока все хорошо. Давайте теперь получим результат из приведенных выше целых чисел. Это было бы:
a10 * 1 + a9 * 256 + a8 * 256² + ...
Или, используя ограниченные арифметические способности Эликсира:
iex|4 ▶ [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]
...|4 ▷ |> Enum.reverse
...|4 ▷ |> Enum.with_index
...|4 ▷ |> Enum.reduce(0, fn {e, i}, acc ->
...|4 ▷ # ⇓⇓⇓ exact integer i-power of 256 ⇓⇓⇓
...|4 ▷ acc + e * Enum.reduce(List.duplicate(256, i), 1, &Kernel.*/2)
...|4 ▷ end)
#⇒ 237007314493411930484791
Это именно то, что вы получили, когда попросили сопоставить первые 10 позиций по образцу с 10-значным числом на основе 256.
Похожие вопросы
Новые вопросы
string
Строка - это конечная последовательность символов, обычно используемая для текста, хотя иногда для произвольных данных.