cod*_*ons 8 containers variable-assignment rakudo raku
在完成我即将发布的关于 sigils 的 Raku Advent Calendar 帖子时,我决定仔细检查我对 sigils 创建的类型约束的理解。文档使用下表描述了印记类型约束\n:
\n
\n根据这张表(以及我对印记和容器如何工作的一般理解),我强烈期望这段代码
\nmy %percent-sigil is List = 1,2;\nmy @at-sigil is Map = :k<v>;\nRun Code Online (Sandbox Code Playgroud)\n抛出错误。
\n具体来说,我预计is List会尝试将 -sigiled 变量绑定%到 a List,并且这会抛出X::TypeCheck::Binding错误 \xe2\x80\x93 ,与抛出的错误相同my %h := 1,2。
但它并没有出错。第一行创建的 aList除了其变量上的印记之外,在各方面看起来都非常普通。第二个创建了一个看似正常的Map。他们俩都没有秘密的Scalar中间人,至少据我通过VAR类似的内省得知。
我快速浏览了World.nqp 源代码%,并且丢弃类型约束似乎is List是预期的行为。
那么,这种行为是否正确/有意?如果是这样,为什么?这如何与 sigils 通常提供的类型约束和其他保证相适应?
\n(我必须承认,看到一个%不支持关联索引的 -sigiled 变量让我感到震惊\xe2\x80\xa6)
我认为这是一个灰色地带,介于 DIHWIDT(Docter,当我这样做时会很受伤)和实施过程中的监督之间。
事实是,您可以创建自己的类并在is特征中使用它。Hash基本上,这会覆盖从默认值(for %) 和Array(for @sigils)创建对象所使用的类型。只要您提供接口方法,它(当前)就可以工作。例如:
class Foo {
method AT-KEY($) { 42 }
}
my %h is Foo;
say %h<a>; # 42
Run Code Online (Sandbox Code Playgroud)
但是,如果您想将这样的对象作为参数传递给%签名中带有印记的 sub,它将失败,因为该类没有消耗该Associatve角色:
sub bar(%) { 666 }
say bar(%h);
===SORRY!=== Error while compiling -e
Calling bar(A) will never work with declared signature (%)
Run Code Online (Sandbox Code Playgroud)
我不确定为什么在编译时不使用该特征强制执行Associative(for the %sigil) 和Positional(for ) 的测试。我认为这是一个疏忽,也许需要在 6.e 中修复。@is