为什么我看到标量上的下标有奇怪的行为?

Why do I see odd behavior of subscript on scalars?

看起来标量本身就像是一个包含一项的列表:

> "foo"[1]
Index out of range. Is: 1, should be in 0..0
  in block <unit> at <unknown file> line 5

> "foo"[0]
foo
> "foo"[*-1]
foo

我说的是一个列表,因为列表的索引似乎没有范围:

> (0, 1, 2)[3]
Nil

这是怎么回事。我对 [] 运算符有什么不了解。

这是Any的一个特点。来自 the docs:

Since Perl 6 intentionally confuses items and single-element lists, most methods in Any are also present on class List, and coerce to List or a list-like type.

如果您 look at the implementation,您会发现没有必要的实际强制转换,因为 Any 提供了 AT-POS,这就是索引不同于 0 的原因。

相比之下,implementation of actual lists 仅在负索引的情况下失败,returns Nil 否则失败。

从语义上讲,这并不完全是疯狂的,因为可以将 Nil 视为一种安静的失败,但这确实是一种不一致。它 可能 是设计使然,因为项目的 'listiness' 只是一个方便的功能,而不是界面本身的一部分,因此如果被误用可能会大声抱怨。

注意Array默认返回Any给出了第三种行为,这可以在自动激活的上下文中理解。

It appears as if a scalar by itself is sort of a list of one item

如果您明确地将列表操作应用于标量,它的行为就好像它是一个包含一个元素的列表,该元素是该标量值。

What am I not understanding about the [] operator.

根据列表的"shape"检查列表(任何Positional数据结构;列表是列表但列表可能不是列表)的索引操作,"Indexing ranges".

您只能显式声明数组的索引范围。

# Value treated as list    shape   Indexing range

'a scalar value'           (1)     0..0         
(0,1,2)                    (*)     0..Inf
my @a                      (*)     0..Inf
my @b[42]                  (42)    0..41

(我对列表(例如 (0,1,2))感到有点惊讶,它具有不可变的形状,被分配了 (*) 的形状。为什么不 (3) (在这种情况下一个 3 元素列表)如果这是已知且不可变的?(也许不是?))