class Pair does Associative {}

由两部分组成,一个和一个Pair可以看作是Hash中的原子单元,它们还与命名参数一起使用。

有许多用于创建Pair的语法

Pair.new('key''value'); # The canonical way 
'key' => 'value';         # this... 
:key<value>;              # ...means the same as this 
:key<value1 value2>;      # But this is  key => <value1 value2> 
:foo(127);                # short for  foo => 127 
:127foo;                  # the same   foo => 127

请注意,最后一种形式也支持非 ASCII 数字

# use MATHEMATICAL DOUBLE-STRUCK DIGIT THREE 
say (:𝟛math-three);         # OUTPUT: «math-three => 3␤»

但不是合成的(即由数字和附加的 Unicode 标记组成)

say :7̈a

您还可以将标识符式字面量用作键;只要它遵循普通标识符的语法,就不需要引号

(foo => 127)              # the same   foo => 127

它的变体是

:key;                     # same as   key => True 
:!key;                    # same as   key => False

以及此其他变体,用于例程调用

sub colon-pair:$key-value ) {
    say $key-value;
}
my $key-value = 'value';
colon-pair:$key-value );               # OUTPUT: «value␤» 
colon-pairkey-value => $key-value );   # OUTPUT: «value␤» 

冒号对可以不带逗号地连接起来,以创建对列表。根据上下文,在分配冒号列表时您可能必须明确指定。

sub s(*%h){ say %h.raku };
s :a1:b2;
# OUTPUT: «{:a1, :b2}␤» 
 
my $manna = :a1:b2:c3;
say $manna.^name;
# OUTPUT: «Pair␤» 
 
$manna = (:a1:b2:c3);
say $manna.^name;
# OUTPUT: «List␤»

任何变量都可以变成其名称和值的Pair

my $bar = 10;
my $p   = :$bar;
say $p# OUTPUT: «bar => 10␤»

值得注意的是,当将Scalar分配为Pair的值时,该值将保存该值本身的容器。这意味着可以从Pair本身外部更改该值

my $v = 'value A';
my $pair = => $v;
$pair.say;  # OUTPUT: «a => value A␤» 
 
$v = 'value B';
$pair.say;  # OUTPUT: «a => value B␤» 

另请注意,此行为与用于构建Pair本身的方式(即显式使用new、使用冒号、胖箭头)以及Pair是否绑定到变量完全无关。

可以通过方法freeze更改上述行为,强制Pair删除标量容器并保存有效值本身

my $v = 'value B';
my $pair = => $v;
$pair.freeze;
$v = 'value C';
$pair.say# OUTPUT: «a => value B␤» 

由于 Pair 实现了Associative角色,因此可以使用关联订阅运算符访问其值,但是,由于 Pair 的单一性质,只有对的键才会返回对的值。对于任何其他键,将返回Nil对象。可以在 Pair 上使用订阅副词,例如:exists

my $pair = => 5;
say $pair<a>;           # OUTPUT: «5␤» 
say $pair<a>:exists;    # OUTPUT: «True␤» 
say $pair<no-such-key># OUTPUT: «Nil␤» 

方法§

方法 new§

multi method new(Pair: Mu  $keyMu  $value)
multi method new(Pair: Mu :$keyMu :$value)

构造一个新的Pair对象。

方法 ACCEPTS§

multi method ACCEPTS(Pair:D $: %topic)
multi method ACCEPTS(Pair:D $: Pair:D $topic)
multi method ACCEPTS(Pair:D $: Mu $topic)

如果%topic是一个Associative,则使用调用者的键在其中查找值,并检查调用者的值.ACCEPTS该值

say %(:42a) ~~ :42a; # OUTPUT: «True␤» 
say %(:42a) ~~ :10a; # OUTPUT: «False␤»

如果 $topic 是另一个 Pair,则检查调用者的键和值,.ACCEPTS 分别接受 $topic 的键和值

say :42~~ :42a; # OUTPUT: «True␤» 
say :42~~ :42a; # OUTPUT: «False␤» 
say :10~~ :42a; # OUTPUT: «False␤»

如果 $topic 是任何其他值,则调用者 Pair 的键被视为方法名。此方法在 $topic 上调用,其 Bool 结果与调用者 PairBool 值进行比较。例如,可以使用 smartmatch 测试素数

say 3 ~~ :is-prime;             # OUTPUT: «True␤» 
say 3 ~~  is-prime => 'truthy'# OUTPUT: «True␤» 
say 4 ~~ :is-prime;             # OUTPUT: «False␤»

此表单还可用于检查同一对象(例如 IO::Path)上多个方法的 Bool 值,方法是使用 Junction

say "foo" .IO ~~ :f & :rw# OUTPUT: «False␤» 
say "/tmp".IO ~~ :!f;      # OUTPUT: «True␤» 
say "."   .IO ~~ :f | :d;  # OUTPUT: «True␤»

方法 antipair§

method antipair(Pair:D: --> Pair:D)

返回一个新的 Pair 对象,其中键和值交换。

my $p = (=> 'Raku').antipair;
say $p.key;         # OUTPUT: «Raku␤» 
say $p.value;       # OUTPUT: «d␤»

方法 key§

multi method key(Pair:D:)

返回 Pair部分。

my $p = (Raku => "d");
say $p.key# OUTPUT: «Raku␤»

方法 value§

multi method value(Pair:D:is rw

返回 Pair部分。

my $p = (Raku => "d");
say $p.value# OUTPUT: «d␤»

中缀 cmp§

multi infix:<cmp>(Pair:DPair:D)

与类型无关的比较器;比较两个 Pair。首先比较它们的部分,然后在键相等的情况下比较部分。

my $a = (Apple => 1);
my $b = (Apple => 2);
say $a cmp $b# OUTPUT: «Less␤»

方法 fmt§

multi method fmt(Pair:D: Str:D $format --> Str:D)

采用格式字符串,并返回格式化 Pair部分的字符串。这是一个示例

my $pair = :Earth(1);
say $pair.fmt("%s is %.3f AU away from the sun")
# OUTPUT: «Earth is 1.000 AU away from the sun␤»

有关格式字符串的更多信息,请参阅 sprintf

方法 kv§

multi method kv(Pair:D: --> List:D)

返回一个包含部分的双元素 List Pair,按该顺序。此方法是 Hash 上同名方法的一个特例,它将所有条目作为键和值列表返回。

my $p = (Raku => "d");
say $p.kv[0]; # OUTPUT: «Raku␤» 
say $p.kv[1]; # OUTPUT: «d␤»

方法 pairs§

multi method pairs(Pair:D:)

返回一个包含一个 Pair 的列表,即此列表。

my $p = (Raku => "d");
say $p.pairs.^name# OUTPUT: «List␤» 
say $p.pairs[0];    # OUTPUT: «Raku => d␤»

方法 antipairs§

multi method antipairs(Pair:D:)

返回一个包含调用者 antipairList

my $p = (=> 'Raku').antipairs;
say $p.^name;                                     # OUTPUT: «List␤» 
say $p.first;                                     # OUTPUT: «Raku => d␤» 
say $p.first.^name;                               # OUTPUT: «Pair␤»

方法 invert§

method invert(Pair:D: --> Seq:D)

返回一个 Seq。如果调用者的 .value 不是 Iterable,则 Seq 将包含一个 Pair,其 .key 是调用者的 .value,其 .value 是调用者的 .key

:foo<bar>.invert.raku.say# OUTPUT: «(:bar("foo"),).Seq␤»

如果调用者的 .value Iterable,则返回的 Seq 将包含与 .value 中的项目一样数量的 Pair,其中每个项目都是一对的 .key,而调用者的 .key 是该对的 .value

:foo<Raku is great>.invert.raku.say;
# OUTPUT: «(:Raku("foo"), :is("foo"), :great("foo")).Seq␤» 
 
:foo{ :42a, :72}.invert.raku.say;
# OUTPUT: «((:a(42)) => "foo", (:b(72)) => "foo").Seq␤»

要执行精确的 .key.value 交换,请使用 .antipair 方法

方法 keys§

multi method keys(Pair:D: --> List:D)

返回一个包含调用者 keyList

say (Raku => "d").keys;                           # OUTPUT: «(Raku)␤»

方法 values§

multi method values(Pair:D: --> List:D)

返回一个包含调用者 valueList

say (Raku => "d").values;                         # OUTPUT: «(d)␤»

方法 freeze§

method freeze(Pair:D:)

通过从其 标量容器 中删除 Pair,使其变为只读,并返回它。

my $str = "apple";
my $p = Pair.new('key'$str);
$p.value = "orange";              # this works as expected 
$p.say;                           # OUTPUT: «key => orange␤» 
$p.freeze.say;                    # OUTPUT: «orange␤» 
$p.value = "a new apple";         # Fails 
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Str (apple)␤»

注意:此方法在 6.d 语言版本中已弃用。相反,创建一个新的 Pair,其中包含 去容器化 的键/值。

$p.=Map.=head.say;                                    # OUTPUT: «orange␤» 

方法 Str§

multi method Str(Pair:D: --> Str:D)

返回一个字符串表示形式的调用者,格式为 key ~ \t ~ value

my $b = eggs => 3;
say $b.Str;                                       # OUTPUT: «eggs  3␤»

方法 Pair§

method Pair()

返回调用者 Pair 对象。

my $pair = eggs => 3;
say $pair.Pair === $pair;                         # OUTPUT: «True␤»

类型图§

Pair 的类型关系
raku-type-graph Pair Pair Any Any Pair->Any Associative Associative Pair->Associative Mu Mu Any->Mu

展开上面的图表