Whatever
是一个其对象没有任何明确含义的类;它从接受 Whatever
对象作为标记以执行特殊操作的其他例程中获取其语义。将 *
文字用作操作数会创建一个 Whatever
对象。
*
的魅力很大程度上来自于Whatever 准备。当 *
用于术语位置(即作为操作数)与大多数运算符结合使用时,编译器会将表达式转换为 WhateverCode
类型的闭包,它实际上是一个可以在接受 Callable
的任何地方使用的 Block
。
my = * + 2; # same as -> $x { $x + 2 };say (4); # OUTPUT: «6»
一个表达式中的多个 *
会生成具有多个参数的闭包
my = * + *; # same as -> $x, $y { $x + $y }
在复杂表达式中使用 *
也会生成闭包
my = 4 * * + 5; # same as -> $x { 4 * $x + 5 }
对 *
调用方法也会创建一个闭包
<a b c>.map: *.uc; # same as <a b c>.map: -> $char { $char.uc }
如前所述,并非所有运算符和语法结构都能将 *
(或 Whatever
星号)准备为 WhateverCode
。在以下情况下,*
将仍然是 Whatever
对象。
异常 | 示例 | 它的作用 |
---|---|---|
逗号 | 1, *, 2 | 生成一个包含 * 元素的列表 |
范围运算符 | 1 .. * | 从 1 到 Inf 的范围 |
系列运算符 | 1 ... * | 无限延迟 Seq |
赋值 | $x = * | 将 * 赋值给 $x |
绑定 | $x := * | 将 * 绑定到 $x |
列表重复 | 1 xx * | 生成一个无限列表 |
范围运算符的处理方式很特殊。它们不会使用 Whatever
星号准备,但它们会使用 WhateverCode
准备。
say (1..*).^name; # OUTPUT: «Range»say ((1..*-1)).^name; # OUTPUT: «WhateverCode»
这允许所有这些结构都能工作
.say for 1..*; # infinite loop
和
my = 1..4;say [0..*]; # OUTPUT: «(1 2 3 4)»say [0..*-2]; # OUTPUT: «(1 2 3)»
因为Whatever 准备是一个纯粹的语法编译器转换,所以你不会在运行时将存储的 Whatever
星号准备为 WhateverCode
。
my = *;+ 2; # Not a closure, dies because it can't coerce $x to NumericCATCH ;# OUTPUT: «X::Multi::NoMatch: Cannot resolve caller Numeric(Whatever: );# none of these signatures match:# (Mu:U \v: *%_)»
存储的 Whatever
星号的用例涉及上面提到的那些准备异常情况。例如,如果你想要一个默认的无限级数。
my = potential-upper-limit() // *;my = known-lower-limit() ... ;
在智能匹配的特定情况下,存储的 *
也会生成 WhateverCode
。请注意,这实际上并不是正在准备的存储的 *
,而是左侧的 *
。
my = find-constraint() // *;my = * ~~ ;
如果这个假设的 find-constraint
没有找到约束,那么 $maybe-always-matcher
将对任何事物求值为 True
。
(555); # True(Any); # True
HyperWhatever
的功能类似于 Whatever
,不同之处在于它引用多个值,而不是单个值。
方法§
方法 ACCEPTS§
multi method ACCEPTS(Whatever: Mu )multi method ACCEPTS(Whatever: Mu )
如果调用者是 一个实例,总是返回 True
。如果调用者是一个类型对象,则执行类型检查。
say 42 ~~ (*); # OUTPUT: «True»say 42 ~~ Whatever; # OUTPUT: «False»
方法 Capture§
method Capture()
抛出 X::Cannot::Capture
。