Как преобразовать параметры цикла в массив фиксированного размера?
Я пытаюсь поместить параметры цикла for в массив ФИКСИРОВАННОГО размера. Вот что я делал (хочу использовать массив @m из 3 элементов):
for (1..19).rotor(3, :partial) -> @m { say @m; } # works, but I cannot specify size of @m
Однако все следующее дает мне ошибки:
for (1..19).rotor(3, :partial) -> @m[0,1,2] { say @m; }
===SORRY!=== Error while compiling:
Variable '@m' is not declared
------> ).rotor(3, :partial) -> @m[0,1,2] { say ⏏@m; }
for (1..19).rotor(3 => -2) -> @m[0..2] { say @m; }
===SORRY!=== Error while compiling:
Variable '@m' is not declared
------> 1..19).rotor(3 => -2) -> @m[0..2] { say ⏏@m; }
for (1..19).rotor(3 => -2) -> @m[3] { say $_; say @m; }
===SORRY!=== Error while compiling:
Variable '@m' is not declared
------> ).rotor(3 => -2) -> @m[3] { say $_; say ⏏@m; }
Итак, как мне указать, что массив @m должен содержать только 3 элемента?
2 ответа
В названии вопроса упоминается деструктуризация, но речь идет о разборке чего-либо. Например, с его помощью мы могли бы извлечь три элемента:
for (1..19).rotor(3, :partial) -> [$a, $b, $c] {
}
Однако на самом деле это не кажется проблемой деструктурирования, поскольку запрос состоит не в том, чтобы разбить переданный агрегат на части, а преобразовать его в агрегат другого типа.
Посмотрим немного дальше на вопрос:
Я пытаюсь поместить параметры цикла for в массив ФИКСИРОВАННОГО размера.
Дело в том, rotor
не производит (изменяемый) Array
s вообще. Вместо этого при написании:
for (1..19).rotor(3, :partial) -> @m {
}
потом @m
это List
. АList
является неизменным (и, таким образом, неявно его размер фиксируется при создании), поэтому, если намерение состоит в том, чтобы не было случайного изменения размера, это уже сертификат. К сожалению, конечная цель не была обозначена.
Если действительно хотите превратить переданный неизменяемый List
в форме Array
, ничего не остается, кроме как присвоить ему новый фиксированный размер Array
:
for (1..19).rotor(3, :partial) -> @l {
my @arr[3] = @l;
}
Конечно, это взорвется, если :partial
приводит к остаткам элементов; можно было сделать:
for (1..19).rotor(3, :partial) -> @l {
my @arr[@l.elems] = @l;
}
Чтобы этого не произошло. Однако, если цель - гарантировать, что все взорвется, если когда-нибудь останутся остатки элементов, то либоwhere
:
for (1..19).rotor(3, :partial) -> @m where .elems == 3 {
}
Или, что менее ясно, деструктура на выброс:
for (1..19).rotor(3, :partial) -> @m [$,$,$] {
}
Сделал бы это.
Так что -> @m[3]
это то, что вы хотите, но при этом назначаете подпись вашему анонимному блоку, который ожидает сформированный массив, и вы передаете список.
Так что в итоге я мог превратить мой список в сформированный массив.
for (1..19).rotor(3, :partial).map( { Array.new(:shape(3),$_ ) } ) -> @m[3] { say @m; }
И тогда все работает нормально. Возможно, есть способ сделать это лучше.