raku - 打电话而不打电话给其他候选人?什么是“其他候选人”?它是否耗尽了其他候选人的名单?该列表可用吗?
问题描述
我正在尝试解决这个问题,该问题实际上是由与and的不同行为相关的另一个 stackoverflow 问题提出的。后者似乎已明确定义,但是.callwith
samewith
callwith
看看这个例子:
proto how-many(|) {*}
multi sub how-many( Pair $a, Pair $b ) {
say "Int $a and $b";
return "There are $a and $b"
}
multi sub how-many( $a, $b ) {
say "Not int $a and $b";
my $calling = callwith( 1 => $a, 2 => $b );
return $calling;
}
say how-many( "little piggie","littler piggie" );
根据文档,callwith
应该调用下一个匹配的候选人。但是,这是输出:
Not int little piggie and littler piggie
(Any)
所以它调用 的第二个版本how-many
,然后调用一个不存在的函数(显然)并返回Nil
,它被传递Any
给调用例程。
我也尝试过使用不同的签名,但这也不起作用。文档中的示例显然表明它仅在变量属于同一类层次结构时才有效。是这样吗?可能不是,因为将位置签名更改为Any $a, Any $b
也不起作用,也不会更改声明的顺序。
上面,改变
callwith
显然samewith
会起作用,但我试图了解如何callwith
工作,而不是让上面的代码工作。
此外,它似乎在类层次结构中下降,但没有上升。这个Perl 6 测试套件bake 中的示例有效:
my $tracker = '';
multi d($x) { $tracker ~= 'Any' ~ $x };
multi d(Int $x) { $tracker ~= 'Int'; callwith($x+1); $tracker ~= 'Int' };
lives-ok { d(3) }, 'can call callwith inside a multi sub';
但是,如果我们更改它以便我们callwith
从层次结构的底部使用,如下所示:
my $tracker = '';
multi d($x) { $tracker ~= 'Any' ~ callwith( "called-with" => $x) };
multi d(Pair $x) { $tracker ~= "Pair $x" };
say d( 3 );
它失败了
Use of Nil in string context in sub d at rewrite-test-callwith.p6 line 6
这是预期的行为吗?
解决方案
所有callwith
, nextwith
,callsame
和nextsame
遍历由原始参数确定的候选集。因此,虽然callwith
可以用来替换参数,但这就是它所做的一切。它不会导致要迭代的预定候选人列表发生变化。
考虑这三个候选人:
multi foo(Any $x) { say "In Any case with $x" }
multi foo(Real $x) { say "In Real case with $x"; callwith($x.Int); }
multi foo(Int $x) { say "In Int case with $x"; callsame(); }
我们可以询问哪些候选人使用.cando
并通过了Capture
. 因此:
.say for &foo.cando(\(42));
将产生以下输出:
sub foo (Int $x) { #`(Sub|78402328) ... }
sub foo (Real $x) { #`(Sub|78412816) ... }
sub foo ($x) { #`(Sub|78412968) ... }
由于所有 3 位候选人都匹配。调用foo(42)
将产生以下输出:
In Int case with 42
In Real case with 42
In Any case with 42
相比之下,与:
.say for &foo.cando(\(4.2));
输出是:
sub foo (Real $x) { #`(Sub|78412816) ... }
sub foo ($x) { #`(Sub|78412968) ... }
并且调用foo(4.2)
会callwith
遍历这些候选人:
In Real case with 4.2
In Any case with 4
callwith
最一般的候选中的A或类似将不会有任何影响,并且将评估为Nil
。
虽然这里的示例是多子,但同样适用于包装器和非多方法,它们也遍历预定列表。
最后,还值得观察的是,如果每次都有新的调度,我给出的示例最终将成为无限递归。通过走预先确定的候选人名单,这永远不会发生。
请注意,这些都不适用于samewith
,它的存在正是为了进行全新的调度。
推荐阅读
- symfony - Symfony 5.2 - 在 Twig 中渲染刺激控制器
- arrays - 我如何找出c中的数组中有多少可用空间?
- node.js - 如何将变量添加到文本区域(MERN)
- python-3.x - 使用 Pyinstaller 打包 SpaCy 模型:E050 找不到模型
- qml - 如何将两个按钮右对齐?
- firebase - Flutter + Firebase - 在多个设备上同步倒计时
- reactjs - 反应加载功能
- java - 带有int键和字符串的AVL树?
- php - 在 Symfony 中提交表单时出现验证错误
- c# - 将 LDAP 身份验证集成到 ASP.NET MVC4