是否有 Perl 6 等同于字节数组?
Is there a Perl 6 equivalent of a byte array?
让我们举一个byte[] data
的Java例子。在 Perl 的方法签名中,我可以做 method myMethod($data)
但这是一种有用的动态类型形式。
但是,我希望操作字节数组 - 那么是否有一种首选方法可以将数据类型转换为字节数组或类似的东西?
我环顾四周,在这里看到了将源数据转换为字节数组的代码:
my $arr = Buf.new('mystring'.encode('utf-8'));
say $arr;
这是否只是通过 $data
方法变量操纵 Buf
的方法的首选输入?
不确定这个问题,但这就是你要找的吗?
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
.
用计算机语言详细阅读:
»
是一个hyperoperator, the P6 distillation of SPMD.
»
迭代其左侧的操作数(左侧操作数对应 SPMD 的 MD 位)并在每次迭代时应用其右侧的操作(对应 SPMD 的 SP 位)。
只有在 SP 和 MD 操作数是 SPMD 安全的情况下才使用 »
,即各个操作不会相互干扰。 (如果您不确定,请改用 for
循环或 map
之类的东西。)在这种情况下,希望您很清楚该操作(使用掩码对每个元素进行按位与运算)是SPMD 安全。
要记住 »
的用法,只需记住它是一个 SPMD 操作 and/or 注意它如何显示两个并行的 >
(提醒您它假定并行语义,即编译器可以自由并行化它)左边大于右边(提醒你左边的操作数是复数,即它可以而且通常确实有多个元素,而右边总是只有一个操作) .
.
这是方法调用运算符。给定左侧的调用者,它调用右侧的方法。
&
&
紧跟在 .
之后,强制将 &
右侧的表达式解释为例程。
{ ... }
.&
之后的大括号代码被解释为闭包(例程)。在闭包内部,$_
(可以读作 "this one")为每个元素别名,这些元素是将操作数迭代到 ».&
.
左侧而产生的
$_ +&= mask
此行的格式为 LHS op= RHS
。这种形式是 shorthand for LHS = LHS op RHS
。所以闭包中的代码是 shorthand for:
$_ = $_ +& mask
即"this one becomes this one bit-wise AND masked with mask".
对于觉得这个答案令人困惑的读者,我深表歉意;请在下面留下评论,我会做出相应的反应,也许会写一个完全不同的、更简单的新答案。我希望 @madcrazydrumma 发现它有趣且有用。
让我们举一个byte[] data
的Java例子。在 Perl 的方法签名中,我可以做 method myMethod($data)
但这是一种有用的动态类型形式。
但是,我希望操作字节数组 - 那么是否有一种首选方法可以将数据类型转换为字节数组或类似的东西?
我环顾四周,在这里看到了将源数据转换为字节数组的代码:
my $arr = Buf.new('mystring'.encode('utf-8'));
say $arr;
这是否只是通过 $data
方法变量操纵 Buf
的方法的首选输入?
不确定这个问题,但这就是你要找的吗?
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
.
用计算机语言详细阅读:
»
是一个hyperoperator, the P6 distillation of SPMD.
»
迭代其左侧的操作数(左侧操作数对应 SPMD 的 MD 位)并在每次迭代时应用其右侧的操作(对应 SPMD 的 SP 位)。
只有在 SP 和 MD 操作数是 SPMD 安全的情况下才使用 »
,即各个操作不会相互干扰。 (如果您不确定,请改用 for
循环或 map
之类的东西。)在这种情况下,希望您很清楚该操作(使用掩码对每个元素进行按位与运算)是SPMD 安全。
要记住 »
的用法,只需记住它是一个 SPMD 操作 and/or 注意它如何显示两个并行的 >
(提醒您它假定并行语义,即编译器可以自由并行化它)左边大于右边(提醒你左边的操作数是复数,即它可以而且通常确实有多个元素,而右边总是只有一个操作) .
.
这是方法调用运算符。给定左侧的调用者,它调用右侧的方法。
&
&
紧跟在 .
之后,强制将 &
右侧的表达式解释为例程。
{ ... }
.&
之后的大括号代码被解释为闭包(例程)。在闭包内部,$_
(可以读作 "this one")为每个元素别名,这些元素是将操作数迭代到 ».&
.
$_ +&= mask
此行的格式为 LHS op= RHS
。这种形式是 shorthand for LHS = LHS op RHS
。所以闭包中的代码是 shorthand for:
$_ = $_ +& mask
即"this one becomes this one bit-wise AND masked with mask".
对于觉得这个答案令人困惑的读者,我深表歉意;请在下面留下评论,我会做出相应的反应,也许会写一个完全不同的、更简单的新答案。我希望 @madcrazydrumma 发现它有趣且有用。