Raku &引用;方法'的发票;分配-KEY';必须是对象实例“;使用赋值运算符时

Raku &引用;方法'的发票;分配-KEY';必须是对象实例“;使用赋值运算符时,raku,Raku,使用键入的键进行哈希 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]”类型的对象。你忘了一个新的吗 我觉得这有误导性;真正的错误是什么?我需要写什么 我已经为哈希变量尝试了%符号,但也不起作用。按照您定义的方式,

使用键入的键进行哈希

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]”类型的对象。你忘了一个新的吗

我觉得这有误导性;真正的错误是什么?我需要写什么


我已经为哈希变量尝试了
%
符号,但也不起作用。

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

这里的死亡赠品就是这样,角色确实如此

此外:

但事实上,错误消息提供了大量信息,包括使用
.new
的建议,正如我在这里所做的那样

我们可以将其缩短为:

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

通过使用定义中的双关语,我们不需要$MAP中间类。

TL;JJ博士的回答是对的,但这个解释让我感到困惑。我目前将您显示的问题视为错误/bug和/或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
如果最好考虑notabug,那么可能应该更改错误消息。虽然我同意JJ的观点,即错误消息实际上是正确的(当您了解raku如何工作并弄清楚发生了什么时),但我认为如果我们不将raku(do)更改为dwim,这仍然是一条LTA错误消息

在令人抓紧的方面,我不清楚如何才能最好地改进错误消息。现在我们有了这个。(参见我在中关于这一点的观点是…错误消息LTA?in.)

另一个解决方案 我已经尝试了哈希变量的
%
符号,但也不起作用

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

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

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

它告诉你的是$MAP是一个类;哦,我想说这是一个角色。您需要实例化它。但是让我检查一下。
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
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
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;