Perl 6 中的 Capture

Capture 的定义:

class Capture does Positional does Associative { }

Capture 是一个用于给 code 对象传递参数的容器。Captures 是签名的另一面 — Captures 在调用方定义实参, 而签名(Signatures) 在被调用方定义形式参数。

当你调用 print $a, $b 时, $a, $b 这部分就是一个 Capture。$a, $b 在这儿是实参。

Captures 包含一个 list-like 部分的位置参数和一个 hash-like 部分的具名参数。对于具名参数, Captures 使用一种略微不同的语法而不是普通的 List。有两种简单的方法生成一个具名参数:

  • 使用一个未引起的键命名一个形参, 后面跟着 =>, 然后跟着参数
  • 使用以形参命名的冒号对儿字面量
say unique 1, -2, 2, 3, as => { abs $_ }; # 1, -2, 3
# ... is the same thing as:
say unique 1, -2, 2, 3, :as({ abs $_ });  # 1, -2, 3
# Be careful not to quote the name of a named parameter:
say unique 1, -2, 2, 3, 'as' => { abs $_ }; # 1, -2, 2, 3, "as" => { ... }

单个独立的 Capture 也能被生成, 存储, 然后供之后使用。 在项(term)那儿前置一个反斜线 \ 能生成一个字面的 Capture。通常, 这个 term 会是一个 terms 的列表, 在这个列表里面, 任何 Pair 字面值会被放在 Capture 的具名部分, 而其它 terms 会被放在Capture 的位置(positional) 部分。

my $c = \(42);               # 带有一个 positional 部分的 Capture        
$c = \(1, 2, a => 'b');      # 带有两个 positional 部分和一个具名部分的 Capture

要使用这样的 Capture, 在函数调用里你可以在这个 Capture 前面使用 | , 那么它看起来会像这个 Capture 中的所有值都被作为实参直接传递这个函数了 — 具名参数作为具名参数传递, 而位置参数会作为位置参数传递。 只要你愿意, 你可以重用这个 Capture 任意次, 甚至使用不同的函数。

my $c = \(4,2,3);
reverse(|$c).say; # 3 2 4
sort(5,|$c).say;  # 2 3 4 5

在签名( Signature) 里面, 可以在不含符号的形参那儿前置一个竖线 | 来创建一个 Capture。这会把余下的参数列表打包到那个形参中:

sub f($a, |c) {
    say c; 
}
f(1, 2, 3, a => 4, b => 5); # c  is  \(2, 3, a => 4, b => 5)

请注意,Capture 仍然是列表,因为它们可能包含容器,而不只是值:

my $b = 1;
my $c = \(4,2,$b,3);
sort(|$c).say;        # 1 2 3 4
$b = 6;
sort(|$c).say;        # 2 3 4 6

你可能感兴趣的:(Perl 6 中的 Capture)