Действительно привязка аргумента к параметру? (Perl6)

Документация Perl6 гласит: "По умолчанию параметры привязаны к своему аргументу и помечены как доступные только для чтения". Но работает следующий код:

# Example 1
sub f1 ( $x ) { say $x.VAR.WHAT; say $x.WHAT; say $x }
f1(1);

выходы:

(Scalar)
(Int)
1

пока этот код:

# Example 2
my $y := 1;
say $y.VAR.WHAT; say $y.WHAT; say $y;

выходы:

(Int)
(Int)
1

Это (Scalar) в выходных данных Example1 я не понимаю: почему существует скаляр, когда я предположительно связываю аргумент Int 1 с идентификатором $x? Кажется, как будто значение 1 получил "назначение" $x, а не "связанный".

1 ответ

Решение

Scalar Контейнеры также используются для обозначения предметов и, таким образом, предотвращают их сплющивание. При отсутствии ограничения типа реализация будет консервативно оборачивать входящий аргумент только для чтения. Scalar контейнер, чтобы избежать неожиданного выравнивания. Сравните это:

sub foo($x) {
    my @a = $x;
    say @a.elems;
}
foo([1,2,3]);

Который выводит 1 (без сплющивания) с без сигилом:

sub foo(\x) {
    my @a = x;
    say @a.elems;
}
foo([1,2,3])

Который выводит 3, поскольку контекст элемента не навязывается. Были Scalar Контейнер не существует, оба будут выводить 3.

В присутствии неIterable ограничение типа, эта упаковка будет опущена. Таким образом, написание:

sub f1(Int $x) {
    say $x.VAR.WHAT;
    say $x.WHAT;
    say $x
}
f1(1)

Будет выводить:

(Int)
(Int)
1

С участием .VAR просто выдавая идентичность на не контейнере.

Другие вопросы по тегам