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。
类型图§
Whatever 的类型关系