5

这是代码:

my @s=<a b c d>;
for @s.kv {
    for ($^k ... @s.elems) {
        printf("%s ", $^v);
    }
    printf("\n");
}

预期输出为:

# a b c d
# b c d
# c d
# d

但它给出了这个错误(可能是其他错误)

key 0, val 1 Too few positionals passed; expected 2 arguments but got 1

它看起来像主循环的位置变量,$^k不能$^v在内循环内部使用。如何解决?谢谢。更新:内循环内的错字已修复

4

2 回答 2

6

因此,对于您想做的事情,我会这样处理:

my @s = <a b c d>;
for ^@s.elems -> $start-index {
    for @s[$start-index..*] -> $value {
        printf("%s ", $value );
    }
    print("\n");
}

虽然我真的会这样做。

my @s = <a b c d>;
(^@s.elems).map( { @s[$_..*].join(" ").say } )

获取从 0 到数组中元素个数的范围。然后每个切片从那里到最后,加入空格并说。

对此类变量的注释$^k仅适用于当前块(因此您的上述代码无法正常工作)。通常,您只是真的想在或其他类似的东西map中使用它们。grep在可能的情况下,我总是建议命名你的变量,这使得它们也被限制在内部块中。

于 2020-01-07T14:29:47.847 回答
6

Scimon Proctor 的回答基本上是正确的,但我会尝试解释为什么您的示例不起作用。对于初学者,kv返回“索引和值的交错序列”,因此:

my @s=<a b c d>;
.say for @s.kv;

印刷

0
a
1
b
2
c
3
d

本质上,您正在为每个键和值执行一轮循环。将它们成对分组使用rotor可能更接近您正在寻找的内容:

.say for @s.kv.rotor(2)

这将返回:

(0 a)
(1 b)
(2 c)
(3 d)

因为有了这个我们得到了索引的值,我们可以做......

my @s=<a b c d>;
for @s.kv.rotor(2) -> ($k, $) {
    "{@s[$_]} ".print for ($k..^@s.elems);
    printf("\n");
}

请注意,内部循环中也存在错误,其范围超出了@s 中的实际索引。但是,同样,Scimon 使用地图的答案要短得多、惯用且直截了当。这只是在缩小您的原始程序。事实上,我们正在丢弃这些值,所以这实际上是:

my @s=<a b c d>;
for @s.keys -> $k {
    "{@s[$_]} ".print for ($k..^@s.elems);
    printf("\n");
}

根本不需要使用 kv ,只需使用keys

于 2020-01-07T17:30:50.047 回答