Как деструктурировать параметры l oop в массив фиксированного размера? - PullRequest
4 голосов
/ 08 апреля 2020

Я пытаюсь поместить параметры в a для l oop в массив размера FIXED. Это то, что я делал (я хочу использовать массив @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 ]

5 голосов
/ 09 апреля 2020

В заголовке вопроса упоминается деструктуризация, но речь идет о разборе чего-либо. Например, мы могли бы извлечь три элемента, используя его:

for (1..19).rotor(3, :partial) -> [$a, $b, $c] {
}

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

Глядя немного дальше на вопрос:

Я пытаюсь поместить параметры в a для l oop в массив ИСПРАВЛЕНО размер.

Дело в том, что rotor вообще не производит (изменяемые) Array с. Вместо этого при записи:

for (1..19).rotor(3, :partial) -> @m {
}

Тогда @m является List. A 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 [$,$,$] {
}

Сделал бы это.

2 голосов
/ 08 апреля 2020

Таким образом, -> @m[3] - это то, что вы хотите, но это назначает подпись анонимному блоку, который ожидает массив в форме, и вы передаете список.

Итак, то, что я в итоге сделал, может привести мой список в форму массива.

for (1..19).rotor(3, :partial).map( { Array.new(:shape(3),$_ ) } ) -> @m[3] { say @m; }

И тогда все работает нормально. Хотя, вероятно, есть лучший способ сделать это.

...