입력 한 키가있는 해시…
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’를 잊었습니까?
오해의 소지가 있습니다. 실제 오류는 무엇이고 대신 무엇을 써야합니까?
나는 이미 %
해시 변수에 대한시길을 시도했지만 작동하지 않습니다.
답변
당신이 그것을 정의한 방식으로, $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 중간 클래스가 필요하지 않습니다.
답변
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
이모 이것은 버그이거나 거의 비슷합니다.
같은 시나리오에서 버그 / 문제가 배열에도 적용됩니다.
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 오류 메시지라고 생각합니다.
손이 닿으면 오류 메시지를 가장 잘 개선 할 수있는 방법이 명확하지 않습니다. 그리고 지금 우리는 이것을 가지고 있습니다. (즉, 약 내 지점 CF 있습니다 … 오류 메시지 LTA?인가 에 내가 쓴 최근의 대답 .)
다른 해결책
나는 이미
%
해시 변수에 대한시길을 시도했지만 작동하지 않습니다.
JJ는 explicit를 사용하여 값으로 초기화하는 솔루션을 제공했습니다 .new
. 그러나 변수에서 제약 조건을 삭제합니다. 그것을 유지하려면 :
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
이상적으로는 constant
필요하지 않으며 언젠가는 필요하지 않지만 특성 구문 분석이 제한적이라고 생각합니다.