does Associative
由两部分组成,一个键和一个值。Pair
可以看作是Hash
中的原子单元,它们还与命名参数一起使用。
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 THREEsay (:𝟛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( : )my = 'value';colon-pair( : ); # OUTPUT: «value»colon-pair( key-value => ); # OUTPUT: «value»
冒号对可以不带逗号地连接起来,以创建对列表。根据上下文,在分配冒号列表时您可能必须明确指定。
sub s(*);s :a1:b2;# OUTPUT: «{:a1, :b2}»my $manna = :a1:b2:c3;say .^name;# OUTPUT: «Pair»= (:a1:b2:c3);say .^name;# OUTPUT: «List»
任何变量都可以变成其名称和值的Pair
。
my = 10;my = :;say ; # OUTPUT: «bar => 10»
值得注意的是,当将Scalar
分配为Pair
的值时,该值将保存该值本身的容器。这意味着可以从Pair
本身外部更改该值
my = 'value A';my = a => ;.say; # OUTPUT: «a => value A»= 'value B';.say; # OUTPUT: «a => value B»
另请注意,此行为与用于构建Pair
本身的方式(即显式使用new
、使用冒号、胖箭头)以及Pair
是否绑定到变量完全无关。
可以通过方法freeze更改上述行为,强制Pair
删除标量容器并保存有效值本身
my = 'value B';my = a => ;.freeze;= 'value C';.say; # OUTPUT: «a => value B»
由于 Pair 实现了Associative
角色,因此可以使用关联订阅运算符访问其值,但是,由于 Pair 的单一性质,只有对的键才会返回对的值。对于任何其他键,将返回Nil
对象。可以在 Pair 上使用订阅副词,例如:exists
。
my = a => 5;say <a>; # OUTPUT: «5»say <a>:exists; # OUTPUT: «True»say <no-such-key>; # OUTPUT: «Nil»
方法§
方法 new§
multi method new(Pair: Mu , Mu )multi method new(Pair: Mu :, Mu :)
构造一个新的Pair
对象。
方法 ACCEPTS§
multi method ACCEPTS(Pair $: )multi method ACCEPTS(Pair $: Pair )multi method ACCEPTS(Pair $: Mu )
如果%topic
是一个Associative
,则使用调用者的键在其中查找值,并检查调用者的值.ACCEPTS
该值
say %(:42a) ~~ :42a; # OUTPUT: «True»say %(:42a) ~~ :10a; # OUTPUT: «False»
如果 $topic
是另一个 Pair
,则检查调用者的键和值,.ACCEPTS
分别接受 $topic
的键和值
say :42a ~~ :42a; # OUTPUT: «True»say :42z ~~ :42a; # OUTPUT: «False»say :10a ~~ :42a; # OUTPUT: «False»
如果 $topic
是任何其他值,则调用者 Pair
的键被视为方法名。此方法在 $topic
上调用,其 Bool
结果与调用者 Pair
的 Bool
值进行比较。例如,可以使用 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: --> Pair)
返回一个新的 Pair
对象,其中键和值交换。
my = (d => 'Raku').antipair;say .key; # OUTPUT: «Raku»say .value; # OUTPUT: «d»
方法 key§
multi method key(Pair:)
返回 Pair
的键部分。
my = (Raku => "d");say .key; # OUTPUT: «Raku»
方法 value§
multi method value(Pair:) is rw
返回 Pair
的值部分。
my = (Raku => "d");say .value; # OUTPUT: «d»
中缀 cmp§
multi infix:<cmp>(Pair, Pair)
与类型无关的比较器;比较两个 Pair
。首先比较它们的键部分,然后在键相等的情况下比较值部分。
my = (Apple => 1);my = (Apple => 2);say cmp ; # OUTPUT: «Less»
方法 fmt§
multi method fmt(Pair: Str --> Str)
采用格式字符串,并返回格式化 Pair
的键和值部分的字符串。这是一个示例
my = :Earth(1);say .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: --> List)
返回一个包含键和值部分的双元素 List
Pair
,按该顺序。此方法是 Hash
上同名方法的一个特例,它将所有条目作为键和值列表返回。
my = (Raku => "d");say .kv[0]; # OUTPUT: «Raku»say .kv[1]; # OUTPUT: «d»
方法 pairs§
multi method pairs(Pair:)
返回一个包含一个 Pair
的列表,即此列表。
my = (Raku => "d");say .pairs.^name; # OUTPUT: «List»say .pairs[0]; # OUTPUT: «Raku => d»
方法 antipairs§
multi method antipairs(Pair:)
my = (d => 'Raku').antipairs;say .^name; # OUTPUT: «List»say .first; # OUTPUT: «Raku => d»say .first.^name; # OUTPUT: «Pair»
方法 invert§
method invert(Pair: --> Seq)
返回一个 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.invert.raku.say;# OUTPUT: «((:a(42)) => "foo", (:b(72)) => "foo").Seq»
要执行精确的 .key
和 .value
交换,请使用 .antipair
方法。
方法 keys§
multi method keys(Pair: --> List)
say (Raku => "d").keys; # OUTPUT: «(Raku)»
方法 values§
multi method values(Pair: --> List)
say (Raku => "d").values; # OUTPUT: «(d)»
方法 freeze§
method freeze(Pair:)
通过从其 标量容器 中删除 Pair
的值,使其变为只读,并返回它。
my = "apple";my = Pair.new('key', );.value = "orange"; # this works as expected.say; # OUTPUT: «key => orange».freeze.say; # OUTPUT: «orange».value = "a new apple"; # FailsCATCH ;# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Str (apple)»
注意:此方法在 6.d 语言版本中已弃用。相反,创建一个新的 Pair
,其中包含 去容器化 的键/值。
.=Map.=head.say; # OUTPUT: «orange»
方法 Str§
multi method Str(Pair: --> Str)
返回一个字符串表示形式的调用者,格式为 key ~ \t ~ value。
my = eggs => 3;say .Str; # OUTPUT: «eggs 3»
方法 Pair§
method Pair()
返回调用者 Pair
对象。
my = eggs => 3;say .Pair === ; # OUTPUT: «True»