class Array is List {}

Array 是一个 List,它强制其所有元素都是标量容器,这意味着你可以分配给数组元素。

Array 实现 Positional,因此提供对 下标 的支持。

注意 从版本 6.d 开始,.raku(2019.11 版本之前的 .perl)可以在多维数组上调用。

如果你想声明特定类型的 Array,你可以使用多种不同的方式

my @foo of Int = 33,44;        # [33 44] 
my @bar is Array[Int= 33,44# [33 44] 

第二个示例对类型进行参数化,仅在 Rakudo 2019.03 中可用。

方法§

方法 gist§

List.gist 完全相同,除了使用方括号作为周围分隔符。

方法 pop§

method pop(Array:D:is nodal

移除并返回数组中的最后一个项目。如果数组为空,则失败。

与许多 Array 方法一样,可以通过相应的 子例程 调用方法 pop。例如

my @foo = <a b># a b 
@foo.pop;        # b 
pop @foo;        # a 
pop @foo;
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::Cannot::Empty: Cannot pop from an empty Array␤»

方法 push§

multi method push(Array:D: **@values is raw --> Array:D)
multi method push(Array:D: \value --> Array:D)
multi method push(Array:D: Slip \values --> Array:D)

将提供的 value 或 values 添加到数组的末尾,并返回修改后的数组。如果任何参数是 Slip,方法 push 将添加参数的 迭代器 生成的值。如果调用数组或 Slip 是惰性的,它会抛出异常。

示例

my @foo = <a b c>;
@foo.push: 'd';
say @foo;                   # OUTPUT: «[a b c d]␤»

请注意,push 不会尝试平铺其参数列表。如果你将数组或列表作为要 push 的内容传递,它将成为一个额外的元素

my @a = <a b c>;
my @b = <d e f>;
@a.push: @b;
say @a.elems;               # OUTPUT: «4␤» 
say @a[3].join;             # OUTPUT: «def␤»

只有当你将多个值作为单独的参数或在 Slip 中提供时,才会将它们添加到数组中

my @a = '1';
say @a.push: 'a''b';       # OUTPUT: «[1 a b]␤» 
my @c = <E F>;
say @a.push: @c.Slip;        # OUTPUT: «[1 a b E F]␤»

如果你想附加由单个非滑动 Iterable 生成的多个值,请参见 方法 append

方法 append§

multi method append(Array:D: **@values is raw --> Array:D)
multi method append(Array:D: \arg --> Array:D)

将提供的 value 添加到数组的末尾并返回修改后的数组,或者如果调用数组或需要平铺的参数 是惰性的,则抛出异常。

方法 push 相反,方法 append 遵守 单参数规则,可能最好将其视为

multi method append(Array:D: +values --> Array:D)

这意味着,如果你传递一个单个参数,该参数是非 项目化 Iterableappend 将尝试平铺它。

例如

my @a = <a b c>;
my @b = <d e f>;
@a.append: @b;
say @a.elems;               # OUTPUT: «6␤» 
say @a;                     # OUTPUT: «[a b c d e f]␤»

方法 elems§

method elems(Array:D: --> Int:D)

返回调用者中的元素数。如果调用者是惰性的,则抛出X::Cannot::Lazy异常。对于形状数组,返回外部维度;如果您需要所有维度的信息,请参阅shape

say [<foo bar ber>.elems# OUTPUT: «3␤» 
say (my @a[42;3;70]).elems# OUTPUT: «42␤» 
 
try [-∞...∞].elems;
say $!.^name;               # OUTPUT: «X::Cannot::Lazy␤»

方法 clone§

method clone(Array:D: --> Array:D)

克隆原始Array。克隆中元素的修改不会传播到原始元素,反之亦然

my @a = <a b c>my @b = @a.clone;
@b[1= 42@a.push: 72;
say @b# OUTPUT: «[a 42 c]␤» 
say @a# OUTPUT: «[a b c 72]␤»

但是,请注意,两个数组之间共享具体化器,因此即使在具体化时每个数组都是随机生成的,并且每个元素只具体化一次,无论具体化是由克隆还是原始数组完成的,两个数组都将具有相同的元素。注意:就像从多个线程具体化数组不安全一样,例如,从一个线程具体化克隆,而从另一个线程具体化原始数组也不安全。

my @a = 1{rand} … ∞; my @b = @a.clone;
say @b[^3]; # OUTPUT: «(1 0.0216426755282736 0.567660896142156)␤» 
say @a[^3]; # OUTPUT: «(1 0.0216426755282736 0.567660896142156)␤»

方法 flat§

multi method flat(Array:U:)
multi method flat(Array:D:)

如果将此方法应用于类型对象,则它将返回类型对象本身;当应用于对象时,它将返回由基础迭代器Array创建的Seq

my @a = <a 2 c>;
say @a.flat.^name# OUTPUT: «Seq␤» 

方法 shift§

method shift(Array:D:is nodal

从数组中移除并返回第一个项目。如果数组为空,则失败。

示例

my @foo = <a b>;
say @foo.shift;             # OUTPUT: «a␤» 
say @foo.shift;             # OUTPUT: «b␤» 
say @foo.shift;
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::Cannot::Empty: Cannot shift from an empty Array␤»

例程 unshift§

multi        unshift(Array:D**@values --> Array:D)
multi method unshift(Array:D: **@values --> Array:D)

@values添加到数组的开头,并返回修改后的数组。如果@values是惰性列表,则失败。

示例

my @foo = <a b c>;
@foo.unshift: 13 ... 11;
say @foo;                   # OUTPUT: «[(1 3 5 7 9 11) a b c]␤»

方法 push 的文档中的注释适用于添加到数组的元素数量。

例程 prepend是添加来自一个列表或数组的多个元素的等效项。

例程 prepend§

sub prepend(\array|values)
multi method prepend(Array:D: \values)
multi method prepend(Array:D: **@values is raw)

将来自values的元素添加到数组的前面,就地修改数组。

示例

my @foo = <a b c>;
@foo.prepend: 13 ... 11;
say @foo;                   # OUTPUT: «[1 3 5 7 9 11 a b c]␤»

与方法unshift的区别在于,如果您预置单个数组或列表参数,prepend将扁平化该数组/列表,而unshift将列表/数组预置为单个元素。

例程 splice§

multi        splice(@list,   $start = 0$elems?*@replacement --> Array)
multi method splice(Array:D: $start = 0$elems?*@replacement --> Array)

Array中删除从索引$start开始的$elems元素,返回它们,并用@replacement替换它们。如果省略$elems或大于从$start开始的元素数,则删除从索引$start开始的所有元素。如果省略$start$elems,则从Array中删除所有元素并返回。

$start$elems 每个都可以指定为 WhateverCallable,后者返回一个与 Int 兼容的值:此返回值随后用作 splice 例程的相应参数。

一个 Whatever $start 使用 @list(或调用者)的元素数量。一个 Callable $start 使用一个参数调用——@list(或 self)中的元素数量。

一个 Whatever $elems$start 删除到 @list(或 self)的末尾(与没有 $elems 相同)。一个 Callable $elems 使用一个参数调用——@list(或 self)中的元素数量减去 $start 的值。

示例

my @foo = <a b c d e f g>;
say @foo.splice(23, <M N O P>);        # OUTPUT: «[c d e]␤» 
say @foo;                                # OUTPUT: «[a b M N O P f g]␤»

它可用于通过简单地拼接比当前大小更多的元素来扩展数组(自版本 6.d 起)

my @foo = <a b c d e f g>;
say @foo.splice(64, <M N O P>);       # OUTPUT: «[g]␤» 
say @foo;                               # OUTPUT: «[a b c d e f M N O P]␤» 

以下等价关系成立(假设 @a.elems ≥ $i

@a.push($x, $y)      @a.splice: *  , *, $x, $y
@a.pop               @a.splice: *-1,
@a.shift             @a.splice: 0  , 1,
@a.unshift($x, $y)   @a.splice: 0  , 0, $x, $y
@a[$i] = $y          @a.splice: $i , 1, $y,

如上所述,可以为 $start$elems 参数提供 WhateverCallable 对象。例如,我们可以使用其中任何一个从数组中删除倒数第二个元素,前提是它足够大以拥有一个

my @foo = <a b c d e f g>;
say @foo.splice: *-2*-1;           # OUTPUT: «[f]␤» 
say @foo;                            # OUTPUT: «[a b c d e g]␤» 
 
my &start     = -> $n { $n - 2 };
my &elems-num = -> $m { $m - 1 };
say @foo.splice: &start&elems-num# OUTPUT: «[e]␤» 
say @foo;                            # OUTPUT: «[a b c d g]␤»

方法 shape§

method shape() { (*,) }

以列表的形式返回数组的形状。

示例

my @foo[2;3= ( < 1 2 3 >, < 4 5 6 > ); # Array with fixed dimensions 
say @foo.shape;                          # OUTPUT: «(2 3)␤» 
my @bar = ( < 1 2 3 >, < 4 5 6 > );      # Normal array (of arrays) 
say @bar.shape;                          # OUTPUT: «(*)␤»

方法 default§

method default

返回调用者的默认值,即在尝试访问 Array 中之前未初始化的元素或访问已明确设置为 Nil 的元素时返回的值。除非使用 is default 特性声明 Array 具有默认值,否则该方法返回 Any 的类型对象。

my @a1 = 1"two"2.718;
say @a1.default;                               # OUTPUT: «(Any)␤» 
say @a1[4];                                    # OUTPUT: «(Any)␤» 
 
my @a2 is default(17= 1"two"3;
say @a2.default;                               # OUTPUT: «17␤» 
say @a2[4];                                    # OUTPUT: «17␤» 
@a2[1= Nil;                                  # (resets element to its default) 
say @a2[1];                                    # OUTPUT: «17␤» 

方法 of§

method of()

返回调用者值的类型约束。默认情况下,即如果在声明期间未给出类型约束,则该方法返回 (Mu)

my @a1 = 1'two'3.14159;              # (no type constraint specified) 
say @a1.of;                              # OUTPUT: «(Mu)␤» 
 
my Int @a2 = 123;                    # (values must be of type Int) 
say @a2.of;                              # OUTPUT: «(Int)␤» 
@a2.push: 'd';
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::TypeCheck::Assignment: Type check failed in assignment to @a2; expected Int but got Str ("d")␤»

方法 dynamic§

method dynamic(Array:D: --> Bool:D)

如果使用 is dynamic 特性声明调用者,即如果它是一个动态变量,可以从内部词法作用域访问而无需在那里声明,则返回 True

my @a;
say @a.dynamic;                          # OUTPUT: «False␤» 
 
my @b is dynamic;
say @b.dynamic;                          # OUTPUT: «True␤»

如果你使用 * twigil 声明一个变量,则隐含 is dynamic

my @*b;
say @*b.dynamic;                         # OUTPUT: «True␤»

请注意,dynamic 特性是变量的属性,而不是内容的属性。如果 Scalar 动态变量包含一个数组,则此容器的规则将适用(并且它将始终返回 False)。

方法 List§

multi method List(Array:D:)

将数组转换为 List

my @array= [1];
@array[3]=3;
say @array.List;       # OUTPUT: «(1 Nil Nil 3)␤» 

孔将显示为 Nil

方法 Slip§

multi method Slip(Array:D: --> Slip:D)

将数组转换为 Slip,使用 Array 定义的类型值填充孔。

my Int @array= [0];
@array[3]=3;
say @array.Slip# OUTPUT: «(0 (Int) (Int) 3)␤» 

Typegraph§

Array 的类型关系
raku-type-graph Array Array List List Array->List Mu Mu Any Any Any->Mu Cool Cool Cool->Any Positional Positional Iterable Iterable List->Cool List->Positional List->Iterable

展开上面的图表