2016-08-18 15 views
8

Tôi nghi ngờ đây có thể là một lỗi trong Rakudo, nhưng tôi mới bắt đầu chơi với Perl 6 ngày hôm nay, vì vậy có một cơ hội tốt tôi đang mắc lỗi. Trong chương trình đơn giản này, việc khai báo một mảng được đánh máy bên trong một sub sẽ xuất hiện để làm cho trình biên dịch Perl 6 trở nên tức giận. Loại bỏ chú thích kiểu trên mảng sẽ loại bỏ lỗi trình biên dịch.Perl 6 báo cáo "Không thể unbox một loại đối tượng" khi gõ một mảng

Dưới đây là một số nguyên tố đơn giản việc tìm kiếm chương trình:

#!/usr/bin/env perl6 
use v6; 

sub primes(int $max) { 
    my int @vals = ^$max; # forcing a type on vals causes compiler error (bug?) 
    for 2..floor(sqrt($max)) -> $i { 
     next if not @vals[$i]; 
     @vals[2*$i, 3*$i ... $max-1] = 0; 
    } 
    return ($_ if .Bool for @vals)[1..*]; 
} 

say primes(1000); 

On Rakudo sao 2016/07/01 (từ Repos Fedora 24), chương trình này cung cấp cho các lỗi sau:

[[email protected] p6test]$ perl6 primes.p6 
Cannot unbox a type object 
    in sub primes at primes.p6 line 8 
    in block <unit> at primes.p6 line 13 

Nếu tôi loại bỏ chú thích loại trên mảng vals, chương trình hoạt động chính xác:

... 
    my @vals = ^$max; # I removed the int type 
    ... 

Tôi có mắc lỗi không trong việc sử dụng Perl 6 của tôi, hay đây là lỗi trong Rakudo?

Trả lời

12

Có một lỗi tiềm năng trong mã của bạn đó là bắt theo loại kiểm tra

Các thông báo lỗi bạn đã thu hút sự chú ý đến dòng 8:

@vals[2*$i, 3*$i ... $max-1] = 0; 

dòng này gán danh sách các giá trị trên bên phải = vào danh sách các phần tử ở bên trái.

Phần tử đầu tiên trong danh sách ở bên trái, @vals[2*$i], lấy số không.

Bạn không xác định thêm bất kỳ giá trị nào ở bên phải để phần còn lại của các phần tử bên trái được gán Mu. Mu s hoạt động tốt như trình giữ chỗ cho các phần tử không có loại cụ thể và không có giá trị cụ thể. Hãy suy nghĩ về một số Mu như là, trong số những thứ khác, như một Null, ngoại trừ việc nó an toàn.

Bạn nhận được kịch bản cùng với điều này golfed phiên bản:

my @vals; 
@vals[0,1] = 0; # assigns 0 to @vals[0], Mu to @vals[1] 

Như bạn đã thấy, mọi thứ hoạt động tốt khi bạn làm không chỉ định một loại hạn chế rõ ràng cho các yếu tố của @vals mảng.

Điều này là do ràng buộc loại mặc định cho các phần tử mảng là Mu. Vì vậy, gán một Mu cho một phần tử là tốt.


Nếu bạn cảm thấy nó thắt chặt lên mã của bạn, bạn có thể gán một cách rõ ràng zero:

@vals[2*$i, 3*$i ... $max-1] = 0 xx Inf; 

này tạo ra một (lười biếng) danh sách vô hạn của zero trên RHS để không được gán cho mỗi danh sách các yếu tố trên LHS.

Chỉ với thay đổi này, mã của bạn sẽ hoạt động ngay cả khi bạn chỉ định loại ràng buộc cho @vals.


Nếu bạn không giới thiệu xx Inf nhưng làm chỉ định một loại yếu tố hạn chế cho @vals đó không phải là Mu, sau đó mã của bạn sẽ thất bại một tấm séc loại nếu bạn cố gắng gán một Mu để một phần tử của @vals.

Lỗi kiểm tra loại sẽ có một trong hai hương vị tùy thuộc vào việc bạn đang sử dụng loại đối tượng hay kiểu gốc.

Nếu bạn chỉ định một loại đối tượng khó khăn (ví dụ Int):

my Int @vals; 
@vals[0,1] = 0; 

sau đó bạn nhận được một cái gì đó lỗi như thế này:

Type check failed in assignment to @vals; expected Int but got Mu (Mu) 

Nếu bạn chỉ định một loại chế bản địa (ví dụ int thay hơn Int):

my int @vals; 
@vals[0,1] = 0; 

t hen trình biên dịch đầu tiên cố gắng để sản xuất một giá trị bản địa phù hợp từ giá trị đối tượng (điều này được gọi là "unboxing") trước khi thử một loại kiểm tra. Nhưng không có giá trị gốc phù hợp với giá trị đối tượng (Mu). Vì vậy, trình biên dịch phàn nàn rằng nó thậm chí không thể unbox giá trị. Cuối cùng, như được gợi ý lúc đầu, trong khi Mu hoạt động tốt như một loại Null an toàn, đó chỉ là một khía cạnh của Mu. Khác là nó là một "type object". Vì vậy, thông báo lỗi là Cannot unbox a type object.

+1

Cảm ơn bạn đã giải thích rõ ràng. Tôi đã ban đầu hy vọng cho nó để hành xử như numpy hoặc MATLAB (mà làm mở rộng danh sách ngầm) nhưng đề nghị của bạn không những gì tôi muốn rõ ràng mà có lẽ là tốt hơn (lười biếng vô hạn danh sách là tuyệt vời). – Sultan

Các vấn đề liên quan