TL; DR JJ jawaban benar, tetapi penjelasannya membuat saya bingung. Saat ini saya melihat masalah yang Anda tunjukkan sebagai kesalahan / bug autovivification dan / atau pesan kesalahan 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 ini bug atau cukup dekat dengan satu.
Bug / masalah juga berlaku untuk array dalam skenario yang sama:
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
Jika itu dianggap terbaik notabug, maka mungkin pesan kesalahan harus diubah. Sementara saya setuju dengan JJ bahwa pesan kesalahan sebenarnya tepat (ketika Anda memahami bagaimana raku bekerja dan mencari tahu apa yang terjadi), saya pikir itu tetap merupakan pesan kesalahan LTA jika kita tidak mengubah raku (do) menjadi dwim.
Di sisi lain, tidak jelas bagiku bagaimana cara terbaik untuk memperbaiki pesan kesalahan. Dan sekarang kita punya SO ini. (cf poin saya tentang bahwa Apakah ... pesan kesalahan LTA? di jawaban terakhir saya menulis .)
Solusi lain
Saya sudah mencoba %
sigil untuk variabel hash, itu juga tidak berhasil.
JJ telah memberikan solusi yang menginisialisasi dengan nilai dengan eksplisit .new
. Tapi itu menghilangkan batasan dari variabel. Untuk mempertahankannya:
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
Idealnya constant
tidak diperlukan, dan mungkin suatu hari tidak, tetapi saya pikir penguraian sifat terbatas.