Есть ли в Perl 6 эквивалент байтового массива?
Давайте возьмем пример Java byte[] data
, В сигнатуре метода для Perl я могу сделать method myMethod($data)
но это форма динамической типизации, которая полезна.
Тем не менее, я хочу манипулировать массивом байтов - так есть ли предпочтительный способ преобразования типов данных в байтовый массив или что-то удаленно подобное?
Я посмотрел вокруг и увидел этот код здесь, чтобы преобразовать исходные данные в байтовый массив:
my $arr = Buf.new('mystring'.encode('utf-8'));
say $arr;
Будет ли это просто предпочтительным входом в мой метод (ы), который будет манипулировать Buf
сквозь $data
переменная метода?
2 ответа
Не уверен насчет вопроса, но это то, что вы ищете?
my int8 @a = ^10; # a native array of 8-bit signed bytes
sub frobnicate(int8 @b) { # a sub taking a native 8-bit array
dd @b;
}
frobnicate @a;
# array[int8].new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Возможно, это полезно:
my \buffer = Buf.new: 'mystring'.encode: 'utf-8';
my \offset = 3;
my \mask = 0x03;
sub mask-buffer-from-to (\mask,
\buffer,
\from = 0,
\to = buffer.end) {
buffer[from..to]».&{ $_ +&= mask }
}
mask-buffer-from-to mask, buffer, offset;
say buffer; # Buf:0x<6d 79 73 00 02 01 02 03>
Я перерезал сигилы (использовал \
в объявлениях переменных вместо $
и т. д.), чтобы уменьшить беспорядок (сокращение символов означает, что они отброшены после объявления). Я надеюсь, что это облегчает чтение. Пожалуйста, дайте мне знать, если это сработало для вас или это действительно усложнило.
= 0
а также = buffer.end
биты в подписи сабвуфера являются значениями по умолчанию.
Если бы вы были достаточно знакомы с P6, было бы очевидно, что ».&{ $_ +&= mask }
выражение означало. Но это не так, поэтому я объясню.
Читая его по-английски, это означает, что, учитывая диапазон элементов буфера слева, выполняется итерация (параллельно, если компилятор желает это сделать) для каждого элемента, побитово И каждый элемент с mask
,
Читая это в computerese, подробно:
»
гипероператор, дистилляция SPMD P6.
»
повторяет операнд слева (левый операнд соответствует биту MD SPMD) и применяет операцию справа (соответствует биту SP SPMD) на каждой итерации.
Использовать только »
если операнды SP и MD безопасны для SPMD, то есть отдельные операции не мешают друг другу. (Если вы не уверены, используйте что-то вроде for
петля или map
вместо этого.) В этом случае, мы надеемся, для вас очевидно, что операция (побитовое И-каждый элемент с маской) безопасна для SPMD.
Чтобы вспомнить, что это за использование »
действительно, просто помните, что это операция SPMD и / или обратите внимание, как он показывает две параллельные >
(чтобы напомнить вам, что он предполагает параллельную семантику, то есть компилятор может распараллелить ее) с левой стороной больше, чем с правой стороны (чтобы напомнить вам, что левый операнд является множественным числом, то есть он может и обычно имеет несколько элементов, тогда как право всегда только одна операция).
.
Это оператор вызова метода. Он вызывает метод справа от данного инвоканта слева.
&
&
сразу после .
заставляет выражение справа от &
быть интерпретированным как рутина.
{ ... }
Скрепленный код сразу после .&
интерпретируется как закрытие (рутина). Внутри закрытия, $_
(который может быть прочитан как "этот") связан с каждым из элементов, полученных в результате итерации операнда слева от ».&
,
$_ +&= mask
Эта строка имеет вид LHS op= RHS
, Эта форма является сокращением для LHS = LHS op RHS
, Таким образом, код в закрытии является сокращением для:
$_ = $_ +& mask
то есть "этот становится этим битовым И замаскирован маской".
Я прошу прощения у читателей, которые считают этот ответ запутанным; Пожалуйста, оставьте комментарии ниже, и я буду реагировать соответственно, возможно, написать совершенно другой, более простой, новый ответ. Я надеюсь, что @madcrazydrumma находит это интересным и полезным.