Câu trả lời của TL; DR JJ là đúng, nhưng lời giải thích khiến tôi bối rối. Tôi hiện đang xem sự cố mà bạn đã hiển thị dưới dạng thông báo lỗi / lỗi tự động và / hoặc thông báo lỗi 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 đây là một lỗi hoặc khá gần với một.
Một lỗi / vấn đề áp dụng cho các mảng quá trong cùng một kịch bản:
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
Nếu nó được coi là tốt nhất, thì có lẽ nên thay đổi thông báo lỗi. Mặc dù tôi đồng ý với JJ rằng thông báo lỗi thực sự là đúng (khi bạn hiểu cách raku hoạt động và tìm hiểu chuyện gì đang xảy ra), tôi nghĩ đó vẫn là một thông báo lỗi LTA nếu chúng ta không thay đổi raku (do) thành lùn.
Về mặt hấp dẫn, đối với tôi, làm thế nào một người có thể cải thiện tốt nhất thông báo lỗi. Và bây giờ chúng ta có SO này. (cf quan điểm của tôi về điều đó trong ... Thông báo lỗi LTA? trong một câu trả lời gần đây tôi đã viết .)
Giải pháp khác
Tôi cũng đã thử %
sigil cho biến băm, điều đó cũng không hoạt động.
JJ đã cung cấp một giải pháp khởi tạo với một giá trị rõ ràng .new
. Nhưng điều đó làm giảm các ràng buộc từ biến. Để giữ lại:
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
Lý tưởng là constant
sẽ không cần thiết, và có lẽ một ngày nào đó sẽ không, nhưng tôi nghĩ rằng phân tích đặc điểm là hạn chế.