Есть ли в 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 находит это интересным и полезным.

Другие вопросы по тегам