4

考虑这个程序,我在参数列表中构造了一个数组。虽然有一个接受数组的签名,但这调用了接受列表的签名:

foo( [ 1, 2, 3 ] );

multi foo ( Array @array ) { put "Called Array @ version" }
multi foo ( Array $array ) { put "Called Array \$ version" }
multi foo ( List $list )   { put "Called List version" }
multi foo ( Range $range ) { put "Called Range version" }

我从一个意外的例程中得到输出:

Called Array $ version

如果我取消注释该其他签名,则该签名称为:

Called List version

为什么不调用( Array @array )版本?调度员如何做出决定(以及记录在哪里)?

4

3 回答 3

5

为什么不调用( Array @array )版本?

您的测试foo调用只有一个 Array ( [1,2,3]) 作为其参数,而不是一个 s 数组 Array例如[[1,2,3],[4,5,6]])。

@in@array表示一个值does Positional,例如一个数组或一个列表。Array @array表示相同的东西,但有一个额外的约束,即数组、列表或任何东西的每个元素都是一个Array。)

调度员如何做出决定?

简化,它选择最窄的匹配类型:

multi foo ( Array       )              {} # Narrowest
multi foo ( List        )              {} # Broader
multi foo ( Positional  )              {} # Broader still
multi foo ( @array      )              {} # Same as `Positional`

的亚型关系图ArrayListPositional

有关详细信息,请参阅jnthn 对相关 SO question 的权威回答

(以及它在哪里记录)?

我不确定文档。多调度看起来非常少。

于 2017-06-19T06:14:56.333 回答
1

我犯了一个非常愚蠢的错误,这就是为什么我没有看到我所期望的。您不能约束以 开头的变量@。任何约束都适用于其元素。Array @array表示我有一种位置类型的东西,其中每个元素都是一个Array. 这和雷夫说的一样。奇怪的是,语法看起来一样,但做的事情却不同。这是我以前绊倒过的东西。

由于它正在做一些不同的事情,即使数据结构匹配,它也不会成功:

foo( [ [1], [2], [3] ] );
foo( [ 1, 2, 3 ] );

multi foo ( Array @array ) { put "Called Array @ version" }
multi foo ( Array $array ) { put "Called Array \$ version" }
multi foo ( List $list )   { put "Called List version" }
multi foo ( Range $range ) { put "Called Range version" }

根据约束和数据结构,我仍然得到我不期望的版本:

Called Array $ version
Called Array $ version

我认为这只是普通用户必须学习的 Perl 6 的缺点之一。

于 2017-07-01T18:55:29.300 回答
0

设计文档(更完整但更过时)和文档(已知不完整,正如 docs.perl6.org 承认的那样,但希望是最新的)之间似乎存在权衡。前者在概要 12中解释了多子分辨率。摘抄:

当您调用具有特定短名称的例程时,如果有多个可见的长名称,则它们都被视为候选。根据参数的运行时类型与每个候选参数的声明类型的匹配程度,它们按顺序排序。最好的候选人被调用,除非有平局,在这种情况下,平局的候选人将使用任何额外的决胜策略重新分配(见下文)。[...]

共有三种决胜模式,按绝望的升序排列:

A)内部或派生范围

B) 运行时约束处理

C) 使用标有“默认”的候选人

决胜局 A 只是更喜欢内部或更多派生范围中的候选者,而不是外部或更少派生范围中的候选者。对于相同范围内的候选人,我们继续进行决胜局 B。

在没有任何限制的情况下,决胜局 A 中的关系会立即故障转移到决胜局 C;如果没有被 C 解决,它们会在编译时警告分派不明确。[...]

我对 Perl 6 的了解不足以证明它的准确性,但它似乎与raith 的回答一致,并且还涵盖了其他基础。

于 2017-06-19T20:07:19.303 回答