为何有时需使用强制转换来访问数组的单个元素?
Raku哈希数组元素遍历的差异原因解析
在以下Raku代码中,原本预期通过(1)的.say for %h{"aaa"}就能将数组的每个元素单独打印在一行,但实际运行时会把整个数组打印为一行;而(2)通过.Array强制转换后,才能逐个打印元素。这一现象的原因如下:
测试代码
use v6; my %h; say ""; say "inserts a scalar"; %h.push: (aaa => "aaa"); %h.say; say ""; say "turns the scalar into an array"; %h.push: (aaa => "AAA"); %h.say; say ""; say "(1) shows all elements of the array in a line"; .say for %h{"aaa"}; say ""; say "(2) shows each element of the array in a line"; .say for %h{"aaa"}.Array;
运行输出
inserts a scalar {aaa => aaa} turns the scalar into an array {aaa => [aaa AAA]} (1) shows all elements of the array in a line [aaa AAA] (2) shows each element of the array in a line aaa AAA
核心原因
Raku的哈希(%开头的变量)中,每个键对应的值都会被自动包裹在Scalar容器中:
- 第一次执行
%h.push: (aaa => "aaa")时,%h<aaa>是一个装着字符串"aaa"的Scalar容器。 - 第二次执行
%h.push时,Raku会自动将Scalar容器内的标量替换为一个Positional类型的List对象,此时%h<aaa>的Scalar容器里装的是这个List。
当你执行.say for %h{"aaa"}时,本质是遍历这个Scalar容器本身——而Scalar作为可迭代对象,只会返回它内部包裹的那个List对象,因此.say会直接打印整个List,呈现为一行[aaa AAA]。
而调用.Array方法时,会解包Scalar容器内的Positional对象,将其转换为Array类型。此时遍历这个Array,会逐个取出其中的元素,因此每个元素会被单独打印一行。
替代方案
除了.Array,你也可以用以下方式实现相同效果:
- 使用
.list方法解包:.say for %h{"aaa"}.list - 使用前缀竖线
|进行解包:.say for |%h{"aaa"}
内容的提问来源于stack exchange,提问作者zentrunix
相关产品推荐
相关产品推荐

