Istnieje potencjalny błąd w kodzie, który złapany przez typ sprawdzania
komunikat o błędzie masz zwraca uwagę na linię 8:
@vals[2*$i, 3*$i ... $max-1] = 0;
Linia ta wyznacza listę wartości po prawej stronie =
do listy elementów po lewej stronie.
Pierwszy element na liście po lewej stronie, @vals[2*$i]
, otrzymuje zero.
Nie zdefiniowałeś więcej wartości po prawej, więc reszta elementów po lewej stronie ma przypisany Mu
. Mu
s ładnie działają jako elementy zastępcze dla elementów, które nie mają określonego typu i nie mają określonej wartości. Pomyśl o wartości Mu
, która jest, między innymi, typu Null, z wyjątkiem tego, że jest bezpieczna.
uzyskać ten sam scenariusz z tego golfed wersję:
my @vals;
@vals[0,1] = 0; # assigns 0 to @vals[0], Mu to @vals[1]
Jak widać, wszystko działa dobrze, gdy robisz nie określić wyraźne ograniczenie typu dla pierwiastków z @vals
szyk.
Jest tak, ponieważ domyślnym ograniczeniem typu dla elementów tablicy jest Mu
. Przypisanie elementu Mu
jest więc w porządku.
Jeśli uważało, że zaostrzone kodu można jednoznacznie przypisać zer:
@vals[2*$i, 3*$i ... $max-1] = 0 xx Inf;
To generuje (lazy) nieskończoną listę zer na RHS tak że zerowy jest przypisany do każdego z lista elementów na LHS.
Po tej zmianie Twój kod zadziała nawet po określeniu ograniczenia typu dla @vals
.
Jeżeli nie robisz wprowadzić xx Inf
ale zrobić określić ograniczenie typu element @vals
że nie jest Mu
, następnie Twój kod nie powiedzie się test typu, jeśli spróbujesz przypisać do Mu
element @vals
.
Błąd sprawdzania typu pojawi się w jednym z dwóch smaków w zależności od tego, czy używasz typów obiektów, czy typów natywnych.
Jeśli określisz ograniczenie typu obiektu (np Int
):
my Int @vals;
@vals[0,1] = 0;
wtedy masz coś błędu takiego:
Type check failed in assignment to @vals; expected Int but got Mu (Mu)
Jeśli określisz natywnego typu ograniczenia (np int
raczej niż Int
):
my int @vals;
@vals[0,1] = 0;
t Kiedy kompilator próbuje najpierw uzyskać odpowiednią wartość natywną od wartości obiektu (to się nazywa "unboxing") przed próbą sprawdzenia typu. Ale nie ma odpowiedniej natywnej wartości odpowiadającej wartości obiektu (Mu
). Tak więc kompilator skarży się, że nie może nawet rozpakować wartości. Wreszcie, jak wskazano na początku, podczas gdy Mu
działa świetnie jako bezpieczny typ Null, to tylko jeden aspekt Mu
. Innym jest to, że jest to "type object". Tak więc komunikat o błędzie jest Cannot unbox a type object
.
Dzięki za jasne wyjaśnienie. Początkowo miałem nadzieję, że będzie się zachowywał jak numpy lub matlab (które niejawnie rozszerzają listę), ale twoja sugestia robi to, co chcę wyraźnie, co może być lepsze (leniwe nieskończone listy są świetne). – Sultan