“ Invocant ของเมธอด 'ASSIGN-KEY' ต้องเป็นอินสแตนซ์ของวัตถุ” เมื่อใช้โอเปอเรเตอร์การมอบหมาย


10

แฮชด้วยแป้นพิมพ์ ...

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

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

$MAP{$f1} = $f2;

สร้างข้อผิดพลาด:

Invocant ของเมธอด 'ASSIGN-KEY' ต้องเป็นอินสแตนซ์ของวัตถุประเภท 'Hash [Foo, Foo]' ไม่ใช่วัตถุประเภทที่มีประเภท 'Hash [Foo, Foo]' คุณลืม '.new' หรือไม่?

ฉันคิดว่ามันทำให้เข้าใจผิด ข้อผิดพลาดจริงคืออะไรและฉันต้องเขียนอะไรแทน

ฉันลองใช้%sigil สำหรับตัวแปร hash แล้วซึ่งไม่ได้ผลเช่นกัน


สิ่งที่กำลังพูดถึงคุณคือ $ MAP เป็นชั้นเรียน OTOMH ฉันจะบอกว่ามันมีบทบาท คุณต้องยกตัวอย่าง แต่ให้ฉันตรวจสอบ
jjmerelo

คำตอบ:


7

ในแบบที่คุณกำหนดมัน$MAPเป็นจริงบทบาท คุณต้องยกตัวอย่าง (จริง ๆ แล้วเล่นสำนวน ) มัน:

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 นั้นถูกต้อง แต่คำอธิบายทำให้ฉันสับสน ฉันกำลังดูปัญหาที่คุณแสดงให้เห็นว่าเป็นautovivificationข้อผิดพลาด / ข้อผิดพลาดและ / หรือข้อผิดพลาด 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

หากเป็นการดีที่สุดที่ควรพิจารณาก็คืออาจมีการเปลี่ยนแปลงข้อความแสดงข้อผิดพลาด ในขณะที่ฉันเห็นด้วยกับ JJ ว่าข้อความแสดงข้อผิดพลาดนั้นเกิดขึ้นจริง (เมื่อคุณเข้าใจว่า raku ทำงานอย่างไรและเข้าใจว่าเกิดอะไรขึ้น) ฉันคิดว่ามันเป็นข้อความแสดงข้อผิดพลาด LTA หากเราไม่เปลี่ยน raku (ทำ) เป็น dwim

ในมือของฉันไม่เห็นชัดเจนว่าจะปรับปรุงข้อความแสดงข้อผิดพลาดได้ดีที่สุดอย่างไร และตอนนี้เรามีสิ่งนี้ (CF จุดของฉันเกี่ยวกับในการที่เป็นข้อผิดพลาด ... ข้อความ LTA?ในคำตอบที่ผ่านมาผมเขียน .)

ทางออกอื่น

ฉันลองใช้%sigil สำหรับตัวแปร hash แล้วซึ่งไม่ได้ผลเช่นกัน

JJ ได้จัดให้มีการแก้ปัญหาที่ initializes .newที่มีค่าที่มีอย่างชัดเจน แต่นั่นทำให้ข้อ จำกัด ลดลงจากตัวแปร เพื่อรักษามัน:

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

เป็นการดีที่constantจะไม่ต้องการและบางทีวันหนึ่งก็ไม่ได้ แต่ฉันคิดว่าการแยกลักษณะมี จำกัด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.