在深入研究 EVAL 子例程的细节之前,我们必须揭示一些关于 protos 原型和多重分派的更多信息。检查以下程序:
proto sub f($x) {
say "proto f($x)";
}
multi sub f($x) {
say "f($x)"
}
multi sub f(Int $x) {
say "f(Int $x)"
}
multi sub f(Str $x) {
say "f(Str $x)"
}
f(2);
f('2');
f(3);
f('3');
这里有三个 multi 函数和一个用 proto 关键字声明的函数。早些时候,我们只看到了函数体为空的原型函数,如:
proto sub f($x) {*}
但这不是必需的。正如我们在示例中所看到的,该函数可以承载正常的函数体:
proto sub f($x) {
say "proto f($x)";
}
运行这个程序:
proto f(2)
proto f(2)
proto f(3)
proto f(3)
所有的调用都被 proto-候选者抓住了。现在,更新它并返回一些专用值的 {*}
块;
proto sub f($x) {
if $x.Str eq '3' {
return {*}
}
say "proto f($x)";
}
if
检查触发其最后两个函数调用的块
f(3);
f('3');
在这些情况下,proto-函数返回 {*}
,这使 Raku 尝试其他候选者。由于对于整数和字符串参数我们有足够多的候选者,编译器可以轻松地选择其中之一:
proto f(2)
proto f(2)
f(Int 3)
f(Str 3)