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

时间:2016-10-09 14:24:44

标签: list indexing range perl6 scalar

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

> "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

这里发生了什么。我对[]运算符的理解不清楚。

2 个答案:

答案 0 :(得分:7)

这是Any的一项功能。来自the docs

  

由于Perl 6故意混淆项目和单个元素列表,Any中的大多数方法也出现在类List上,并强制转换为List或类似列表的类型。< / p>

如果你look at the implementation,你会发现当Any提供AT-POS时,没有必要进行实际的强制,而对于不同于0的索引,这是不合适的。

相反,implementation of actual lists仅在负指数的情况下失败,否则返回Nil

从语义上讲,这并不完全是疯狂的,因为将Nil视为安静失败的一种方式,但确实是一种不一致。 可能是设计的,因为项目的“列表”只是一个便利功能而不是正确的界面的一部分,因此如果误用可能会引起吵闹。

请注意Array默认情况下返回Any会产生第三种行为,这可以在自动生存的背景下理解。

答案 1 :(得分:5)

  

看起来好像标量本身就是一个项目的列表

如果将列表操作显式应用于标量,则其行为就好像它是包含一个标量值的元素的列表。

  

我不了解[]运算符。

根据列表的“形状”(“索引范围”列表)检查列表上的索引操作(任何Positional数据结构;列表是列表但列表可能不是列表)。

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

# 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的情况下)元素列表)如果这是已知的和不可变的?(也许它不是?))