使用“has”声明符进行解构/列表赋值

cod*_*ons 10 constructor destructuring variable-assignment rakudo raku

[我同时遇到了引发这个问题和上一个问题的问题,但我认为这两个问题应该分开。]

\n

该文档描述了使用和变量进行解构赋值,但没有提及它是否可以与变量一起使用。但 Raku 足够一致,我决定尝试一下,而且它似乎有效:myourhas

\n
class C { has $.a; has $.b }\nclass D { has ($.a, $.b) }\nC.new: :a<foo>;  # OUTPUT: \xc2\xabC.new(a => "foo", b => Any)\xc2\xbb\nD.new: :a<foo>;  # OUTPUT: \xc2\xabD.new(a => "foo", b => Any)\xc2\xbb\n
Run Code Online (Sandbox Code Playgroud)\n

然而,这种形式似乎打破了属性默认值:

\n
class C { has $.a; has $.b = 42 }\nclass D { has ($.a, $.b = 42) }\nC.new: :a<foo>;  # OUTPUT: \xc2\xabC.new(a => "foo", b => 42)\xc2\xbb\nD.new: :a<foo>;  # OUTPUT: \xc2\xabC.new(a => "foo", b => Any)\xc2\xbb\n
Run Code Online (Sandbox Code Playgroud)\n

此外,翻转默认位置会提供一条错误消息,可能会提供一些有关正在发生的情况的见解(尽管不足以让我了解上述行为是否正确)。

\n
class D { has ($.a = 42, $.b) }\n# OUTPUT:\n===SORRY!=== Error while compiling:\nCannot put required parameter $.b after optional parameters\n
Run Code Online (Sandbox Code Playgroud)\n

那么,有几个问题:解构赋值是否应该与 一起使用has?如果是这样,默认值的行为是否正确/在使用解构赋值时是否有方法分配默认值?

\n

(我真的希望解构赋值得到支持,并且has可以使用默认值;尽管对于使用真正面向对象的类的人来说,它似乎是一个小众功能,但对于编写更多功能代码的人来说,它非常方便想要使用一个类作为具有固定键的稍微类型安全的哈希。能够编写类似的内容对于此类代码class User { has (Str $.first-name, Str $.last-name, Int $.age) }非常有帮助)

\n

cod*_*ons 0

这是目前 Rakudo 中的一个已知错误。预期的行为是为了has支持列表赋值,这将使语法非常类似于问题工作中显示的语法。

\n

我不确定支持的语法是否是:

\n
class D { has ($.a, $.b = 42) }\nD.new: :a<foo>;  # OUTPUT: \xc2\xabD.new(a => "foo", b => 42)\xc2\xbb\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
class D { has ($.a, $.b) = (Any, 42) }\nD.new: :a<foo>;  # OUTPUT: \xc2\xabD.new(a => "foo", b => 42)\xc2\xbb\n
Run Code Online (Sandbox Code Playgroud)\n

但是,无论哪种方式,都会有一种方法可以使用单个属性has来声明多个属性,同时还为这些属性提供默认值。

\n

目前的预期是,这个 bug 将在RakuAST分支合并后的某个时候得到解决。

\n