Когда имеет смысл использовать переменную без сигилов в Раку?

Можно объявить переменную без сигила с помощью обратной косой черты (например, \some-variable), а затем обратиться к ней без сигила (например, some-variable).

Просто интересно, в каких случаях предпочтительнее использовать переменную без сигилов?

Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
13
0
239
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Объявления формы my \a = expr вводят псевдоним a для выражения expr, не навязывая ему какой-либо контекст, как это сделало бы присваивание сигилированной переменной. Таким образом, их основное использование - это когда вы не хотите иметь какую-либо семантику, связанную с какой-либо сигилой.

Лично я чаще всего использую их, когда создаю конвейеры ленивой обработки и хочу назвать части. В качестве простого примера:

my $fh = open 'somefile';
my \no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for no-comments -> $sig-line {
    ...
}

Grep возвращает Seq, который при повторении выполнит операцию. Если бы вместо этого я использовал переменную @-sigil:

my $fh = open 'somefile';
my @no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for @no-comments -> $sig-line {
    ...
}

Тогда, несмотря на то, что результаты будут такими же, производительность памяти будет совсем другой: присваивание нетерпеливо, если оно не встречает что-то явно помеченное как ленивый, и поэтому все строки без комментариев будут сохранены в @no-comments, а затем итерированы по ним. Таким образом, все эти строки остаются в памяти, тогда как в версии без подписи обработанные строки, если они не хранятся где-либо еще, могут быть удалены сборщиком мусора.

Я мог бы использовать сигил $, но это подразумевает один элемент, а это означает, что если я сделаю это:

my $fh = open 'somefile';
my $no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for $no-comments -> $sig-line {
    ...
}

Это не сработает (будет выполнена одна итерация цикла, связывающая Seq в $sig-line); Я должен был бы каким-то образом преодолеть характер предмета:

my $fh = open 'somefile';
my $no-comments = $fh.lines.grep({ not /^\s*'#'/ });
for $no-comments<> -> $sig-line {
    ...
}

Связанное использование - при написании универсального кода, который не хочет применять какой-либо контекст:

sub log-and-call(&foo, \value) {
    note(value.raku);
    foo(value)
}

Опять же, если бы мы использовали $, мы могли бы добавить оболочку элемента и потенциально повлиять на поведение foo.

Другие варианты использования, которые я видел:

  • Поскольку вы не можете повторно связать такое объявление, его можно использовать для передачи неизменяемости читателю. Тем не менее, это не глубокая неизменность, а просто неизменность того, на что ссылается этот символ.
  • Некоторые люди просто не любят сигилы, поэтому используйте это, чтобы избежать их. Конечно, не самый естественный способ использования Раку, но каждому свое. :-)

jubilatious1 25.11.2022 06:22

Есть места, где компилятор использует сигил для оптимизации, например, присваивание анализируется, компиляция привязки параметров использует его, и я думаю, что есть оптимизации на основе сигилов вокруг интерполяции в регулярных выражениях. Однако, поскольку Scalar является контейнером и, следовательно, объектом, использование сигильной переменной $ вместе с присваиванием подразумевает дополнительное выделение. Однако Scalar контейнеры также часто можно устранить с помощью JIT-анализа и оптимизации скалярной замены. В общем, не все так очевидно!

Jonathan Worthington 28.11.2022 01:15

Поскольку они являются константами, мне нравится использовать их при копировании алгоритмов и формул из учебников.

Это облегчает проверку на наличие ошибок.

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