class WhateverCode is Code { }

WhateverCode 对象是 Whatever-priming 的结果。有关详细信息,请参阅 Whatever 文档。

当您希望控制方法或函数解释任何Whatever star的方式时,您可以使用多重分派和WhateverWhateverCode参数来执行此操作,如下例所示

class Cycle {
      has $.pos;
      has @.vals;
}
 
multi get-val(Cycle $cInt $idx{
      $c.vals[$idx % $c.vals.elems]
}
 
# Define what to do with a stand-alone * as the second argument 
multi get-val(Cycle $cWhatever $idx{
    get-val($c$c.pos);
}
 
# Define what to do with a * WhateverCode in an expression 
multi get-val(Cycle $cWhateverCode $idx{
    get-val($c$idx($c.pos));
}
 
my Cycle $c .= new(:pos(2), :vals(0..^10));
 
say get-val($c3);   # OUTPUT: «3␤» 
say get-val($c*);   # OUTPUT: «2␤» 
say get-val($c*-1); # OUTPUT: «1␤»

WhateverCode does Callable 角色,因此应该可以内省它包含的Callable类型;例如,继续前面的示例,我们可以通过检查签名添加一个处理带有两个参数的WhateverCode的多重

# Define what to do with two * in an expression 
multi get-val(Cycle $cWhateverCode $idx where { .arity == 2 }{
    get-val($c$idx($c.pos$c.vals.elems));
}
 
say get-val($c* + * div 2); # 2 + 10/2 = 7 

但是,请注意,子表达式可能会施加它们自己的Whatever star规则

my @a = (012);
say get-val($c@a[*-1]) # 2, because the star belongs to the Array class 

这会让Whatever stars的所有权变得混乱,所以小心不要做得太过。

您还可以使用Callable类型进行类型约束,以便接受任何Callable,包括WhateverCode

sub run-with-rand (Callable $code{ $code(rand};
run-with-rand *.say;           # OUTPUT: «0.773672071688484␤» 
run-with-rand {.say};          # OUTPUT: «0.38673179353983␤» 
run-with-rand sub { $^v.say }# OUTPUT: «0.0589543603685792␤»

使用&标记的参数进行类型约束效果同样好,并且输入更短

sub run-with-rand (&code{ code time };

Typegraph§

WhateverCode 的类型关系
raku-type-graph WhateverCode WhateverCode Code Code WhateverCode->Code Mu Mu Any Any Any->Mu Callable Callable Code->Any Code->Callable

展开上面的图表