如何在Perl 6中切断数组或数组引用?
在Perl 5中,我可以这样做:
my $d = [0 .. 9];
$#$d = 4;
在Perl 6中,如果我尝试这样做,就会出现错误:
my $d = [0 .. 9];
$d.end = 4; # Cannot modify an immutable Int
这样做是可行的,但看起来不如 Perl 5 的方式美观,并且可能比较昂贵:
$d.=splice(0, 5);
有一种简单的方法:
my $d = [0..9];
$d[5..*] :delete;
如果数组是无限的,那么这可能会产生问题。
$d.splice(5)
也有同样的问题。
在平均情况下,您最好的选择可能是$d = [ $d[^5] ]
,特别是当您对数组一无所知,需要一个可变数组时。
如果您不需要它是可变的,$d = $d[^5]
返回一个列表可能更好。
^5
是干什么的吗?(尤其是当初始元素少于 4 个时) - ysth(Any)
类型的 Array
或 (Nil)
类型的 List
。然后你可以对该元素进行赋值。正如 @ikegami 所称,数组将会“拉伸”。(Array)
、(List)
、(Nil)
、(Any)
不等同,并且行为不同。 - G. Citosplice
可能是最好的选择,但您也可以使用^N
范围构造器快捷方式将其缩短为五个元素(我称之为“直到”“运算符”,但我确定有一个更正确的名称,因为它是Range
的构造器):
> my $d = [ 0 .. 9 ];
> $d.elems
> 10
> $d = [ $d[^5] ]
[0 1 2 3 4]
> $d.elems
5
> $d
[0 1 2 3 4]
“caret”是构建从零开始的数字范围的前缀运算符。
(来自Range
文档)
可以说perl6在某种意义上是“perl风格”的,因为它通常具有某些操作的显式版本(使用一种“可预测”的语法 - 方法、例程和:adverb
等),如果你不熟悉该语言,这些版本是可以理解的,然后是类似于快捷方式的变体。
我不确定哪种方法(splice
与快捷方式相比或像Brad Gilbert提到的使用:delete
)在速度或内存使用方面有优势。如果你运行:
perl6 --profile -e 'my $d = [ 0 .. 9 ]; $d=[ $d[^5] ]'
perl6 --profile -e 'my $d = [ 0 .. 9 ]; $d.=splice(0, 5);'
您可以看到微小的差异,如果与真实的程序和工作负载进行比较,则差异可能更显著。
perl -E 'my $d = [ 0 .. 9 ];$#$d = 4;say @$d'
打印出 01234
,因此在 $d = [ $d[^4] ]
中存在一个偏移错误。 - Brad Gilbertxx
运算符:my $d = [0..9];
$d.pop xx 4; #-> (9 8 7 6)
say $d; #-> [0 1 2 3 4 5]
$d = [0..9];
$d.shift xx 5 #-> (0 1 2 3 4)
say $d; #-> [5 6 7 8 9)
splice(@a, 5);
命令,因为这样不会拉伸数组。(这还可以让你使用期望的元素数量,而不是比期望少一个。同时避免了构建和设置魔法标量的过程。) - ikegami