class Capture { }

Capture 是一个容器,用于将参数传递给代码对象。Capture 是 Signature 的另一面。因此,Capture 是调用者定义的参数,而 Signature 是被调用者定义的参数。例如,当您调用 print $a, $b 时,$a, $b 部分是一个 Capture。

Capture 包含一个类似列表的部分,用于存放位置参数,以及一个类似哈希的部分,用于存放命名参数,因此表现为 PositionalAssociative,尽管它实际上并没有混合这些角色。与任何其他数据结构一样,可以创建、存储和稍后使用独立的 Capture。

可以通过在术语前加上反斜杠 \ 来创建文字 Capture。通常,此术语将是术语的 List,从中将 Pair 文字的 key => value:key<value> 形式放入命名部分,所有其他术语将放入位置部分(包括 'key' => value 形式的 Pair)。

my $a = \(42);                      # Capture with one positional arg 
my $b = \(12verbose => True);   # Capture with two positional args and one named arg 
my $c = \(12:verbose(True));    # same as before 
my $c = \(12'verbose' => True); # Capture with three positional args

重申一下,Capture 中的命名参数必须使用以下两种方式之一创建

  • 使用一个未加引号的键来命名一个参数,后跟 =>,后跟参数。例如,as => by => {1/$_}

  • 使用以参数命名的 冒号对 文字。例如,:into(my %leap-years)

例如

sub greet(:$name:$age{
    "$name$age"
}
 
my $d = \(name => 'Mugen'age => 19);   # OK 
my $e = \(:name('Jin'), :age(20));       # OK 
my $f = \('name' => 'Fuu''age' => 15); # Not OK, keys are quoted.

对于接受两个命名参数 nameagegreet 子例程,Capture $d$e 将正常工作,而 Capture $f 将抛出 Too many positionals passed... 错误。这是因为 'age' => 20 不是命名参数(如上面提到的创建命名参数的两种方式),而是位置参数,而 greet 不期望有位置参数。在 Capture 的上下文中,带引号的键不会创建命名参数。任何 'key' => value 都只是另一个位置参数,因此在使用命名参数创建 Capture 时要小心。

创建 Capture 后,您可以在子例程调用中使用它,方法是在它前面加上一个竖线 |,它将如同 Capture 中的值直接作为参数传递给子例程 — 命名参数将作为命名参数传递,位置参数将作为位置参数传递。您可以根据需要多次重复使用 Capture,甚至可以与不同的子例程一起使用。

say greet |$d;                # OUTPUT: «Mugen, 19␤» 
say greet |$e;                # OUTPUT: «Jin, 20␤» 
my $x = \(423-2);
say reverse |$x;              # OUTPUT: «(-2 3 2 4)␤» 
say sort 5|$x;              # OUTPUT: «(-2 2 3 4 5)␤» 
 
say unique |$xas => {.abs}# OUTPUT: «(4 2 3)␤» 
say unique |$x:as({.abs});  # OUTPUT: «(4 2 3)␤» 
 
my $y = \(173by => {1/$_});
say min |$y;                  # OUTPUT: «7␤», same as min 1, 7, 3, by => {1/$_} 
say max |$y;                  # OUTPUT: «1␤», same as max 1, 7, 3, by => {1/$_}

Signature 中,可以通过在 无 sigil 参数 前加上竖线 | 来创建 Capture。这会将参数列表的其余部分打包到该 capture 参数 中。

sub f($a|c{
    say $a;
    say c;
    say c.^name;
    say c.list# see Methods section 
    say c.hash# see Methods section 
}
 
f 123=> 4:b(5);
# OUTPUT: 
# 1 
# \(2, 3, :a(4), :b(5)) 
# Capture 
# (2 3) 
# Map.new((a => 4, b => 5))

请注意,Capture 仍然是 List,因为它们可能包含容器,而不仅仅是字面值

my $b = 1;
my $c = \(42$b3);
say min |$c;        # OUTPUT: «1␤» 
$b = -5;
say min |$c;        # OUTPUT: «-5␤»

方法§

方法列表§

method list(Capture:D:)

返回 Capture 的位置部分。

my Capture $c = \(235apples => (red => 2));
say $c.list# OUTPUT: «(2 3 5)␤»

方法哈希§

method hash(Capture:D:)

返回 Capture 的命名/哈希部分。

my Capture $c = \(235apples => (red => 2));
say $c.hash# OUTPUT: «Map.new((:apples(:red(2))))␤»

方法元素§

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

返回 Capture 中的位置元素数。

my Capture $c = \(235apples => (red => 2));
say $c.elems# OUTPUT: «3␤»

方法键§

multi method keys(Capture:D: --> Seq:D)

返回 Seq,其中包含所有位置键,后跟所有命名键。对于位置参数,键是从零开始的相应参数序数位置。

my $capture = \(235apples => (red => 2));
say $capture.keys# OUTPUT: «(0 1 2 apples)␤»

方法值§

multi method values(Capture:D: --> Seq:D)

返回 Seq,其中包含所有位置值,后跟所有命名参数值。

my $capture = \(235apples => (red => 2));
say $capture.values# OUTPUT: «(2 3 5 red => 2)␤»

方法键值§

multi method kv(Capture:D: --> Seq:D)

返回 Seq,其中包含交替的 。如果存在,位置键和值先出现,然后是命名键和值。

my $capture = \(23apples => (red => 2));
say $capture.kv# OUTPUT: «(0 2 1 3 apples red => 2)␤»

方法对§

multi method pairs(Capture:D: --> Seq:D)

将所有参数(位置参数后跟命名参数)作为 SeqPair 返回。位置参数的键是其各自的序数值(从零开始),而命名参数的键是其名称。

my Capture $c = \(23apples => (red => 2));
say $c.pairs# OUTPUT: «(0 => 2 1 => 3 apples => red => 2)␤»

方法反对§

multi method antipairs(Capture:D: --> Seq:D)

将所有参数(位置参数后跟命名参数)作为 SeqPair 返回,其中键和值已交换,即值变为键,键变为值。此行为与 <pairs|#method_pairs> 方法相反。

my $capture = \(23apples => (red => 2));
say $capture.antipairs# OUTPUT: «(2 => 0 3 => 1 (red => 2) => apples)␤»

方法布尔§

method Bool(Capture:D: --> Bool:D)

如果 Capture 至少包含一个命名参数或一个位置参数,则返回 True

say \(1,2,3apples => 2).Bool# OUTPUT: «True␤» 
say \().Bool;                   # OUTPUT: «False␤»

方法捕获§

method Capture(Capture:D: --> Capture:D)

返回自身,即调用者。

say \(1,2,3apples => 2).Capture# OUTPUT: «\(1, 2, 3, :apples(2))␤»

方法数字§

method Numeric(Capture:D: --> Int:D)

返回 Capture 中的位置元素数。

say \(1,2,3apples => 2).Numeric# OUTPUT: «3␤»

类型图§

Capture 的类型关系
raku-type-graph Capture Capture Any Any Capture->Any Mu Mu Any->Mu Cool Cool Cool->Any Match Match Match->Capture Match->Cool Grammar Grammar Grammar->Match

展开上面的图表