Как сделать диапазон с .., но с обратным отсчетом - PullRequest
0 голосов
/ 24 сентября 2018

Я хочу, чтобы цикл насчитывал от 5 до 1. Я знаю, что могу легко сделать обратное с помощью оператора ..:

for 1..5 { .print }
12345

Но при использовании оператора .. и реверсированиястороны, кажется, он не генерирует допустимый диапазон, с которым for может работать:

for 5..1 { .print }
Nil

Я знаю, что могу использовать метод reverse для объекта Range:

for (1..5).reverse { .print }
54321

Однако я ожидаю, что у оператора .. есть определенный способ генерировать список номеров за 1 вызов.У меня вопрос, как создать Range, который ведет обратный отсчет с помощью оператора ..?

1 Ответ

0 голосов
/ 24 сентября 2018

Просто используйте 5...1 (обратите внимание на 3 ...):

for 5...1 { .print }
54321

Итератор, который Range.reverse, в основном тот же итератор, что и для форвардов, но повторяется с конца до начала.Помимо дополнительного начального вызова .reverse, не должно быть никакой разницы в исполнении.

За исключением того факта, что for 1..5 { } фактически статически оптимизирован, чтобы вообще не использовать Range внутри.Я предполагаю, что это возможность для дальнейшей статической оптимизации.

РЕДАКТИРОВАТЬ: https://github.com/rakudo/rakudo/commit/2dd02751da гарантирует, что for (1..5).reverse оптимизируется так же, как for 1..5.Это делает его примерно в 6 раз быстрее.

РЕДАКТИРОВАТЬ: Начиная с https://github.com/rakudo/rakudo/commit/dfd6450d74, лучший способ обратного отсчета диапазона - это for 5...1: здесь используется та же оптимизация, что и (1..5).reverse, но она намногоболее читабельно.

...