使用赋值运算符时,“方法'ASSIGN-KEY'的调用者必须是对象实例”


10

带有键入键的哈希...

use v6;
class Foo {}
my Hash[Foo, Foo] $MAP;

my $f1 = Foo.new;
my $f2 = Foo.new;

$MAP{$f1} = $f2;

产生错误:

方法“ ASSIGN-KEY”的调用者必须是“ Hash [Foo,Foo]”类型的对象实例,而不是“ Hash [Foo,Foo]”类型的对象。您是否忘记了“ .new”?

我发现它具有误导性;真正的错误是什么,我该写些什么?

我已经尝试过对%哈希变量使用sigil,但这也不起作用。


这说明$ MAP是一类;OTOMH,我会说这是一个角色。您需要实例化它。但是让我检查一下。
jjmerelo

Answers:


7

按照您定义它的方式,$MAP实际上是一个角色。您需要实例化(实际上是pun):

class Foo {}
my Hash[Foo, Foo] $MAP;

my $map = $MAP.new;

my $f1 = Foo.new;
my $f2 = Foo.new;

$map{$f1} = $f2;
say $map;

这里的死胡同是类不能参数化,角色可以。

也:

say $MAP.DEFINITE; # False
say $map.DEFINITE; # True

但是实际上错误消息是非常有用的,直到.new像我在这里所做的那样,都包含使用的建议。

我们可以将其缩短为:

class Foo {}
my %map = Hash[Foo, Foo].new ;
%map{Foo.new} = Foo.new;
%map.say;

通过从定义中进行修剪,我们不需要$ MAP中间类。


6

TL; DR JJ的回答是正确的,但解释使我感到困惑。我目前查看您显示为自动生存错误/错误和/或LTA错误消息的问题。

say my Any       $Any;        # (Any)
say my Hash      $Hash;       # (Hash)
say my Hash[Int] $Hash-Int;   # (Hash[Int])
$Any<a>          = 42;        # OK
$Hash<a>         = 42;        # OK
$Hash-Int.new<a> = 42;        # OK
$Hash-Int<a>     = 42;        # must be an object instance, not a type object

Imo,这是一个错误或接近一个错误。

在同一情况下,错误/问题也适用于数组:

say my Any       $Any;        # (Any)
say my Array     $Array;      # (Array)
say my Array[Int] $Array-Int; # (Array[Int])
$Any[42]           = 42;      # OK
$Array[42]         = 42;      # OK
$Array-Int.new[42] = 42;      # OK
$Array-Int[42]     = 42;      # Type check failed ... expected Array[Int] but got Array

如果最好将其视为notabug,则应该更改错误消息。虽然我同意JJ的观点,但错误消息实际上是正确的(当您了解raku的工作原理并弄清楚发生了什么情况时),但我认为,如果我们不将raku(do)更改为dwim,则它仍然是LTA错误消息。

在我手上,对我来说还不清楚如何更好地改善错误消息。现在我们有了这个。(请参阅最近写的答案中的...错误消息是否为LTA吗?

另一种解决方案

我已经尝试过对%哈希变量使用sigil,但这也不起作用。

JJ提供了一种使用显式值初始化的解决方案.new。但这从变量中删除了约束。保留它:

class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;

理想情况下constant将不需要,也许有一天将不需要,但是我认为特征解析是有限的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.