为什么 C # 8数组切片特性中新的 hat 操作符索引不从0开始?

C # 8.0介绍了一种方便的数组切片方法——参见 官方 C # 8.0博客文章

访问数组最后一个元素的语法为

var value = new[] { 10, 11, 12, 13 };


int a = value[^1]; // 13
int b = value[^2]; // 12

我想知道为什么反向访问元素的索引从1开始而不是0?有什么技术上的原因吗?

13308 次浏览

官方回答

以下是来自 Mads Torgersen的评论,解释了 C # 8博客文章的设计决策:

当涉及到从开始到结束的算法时,我们决定遵循 Python。0指定第一个元素(一如既往) ,^0指定“ length’th”元素,也就是末尾的那个元素。这样就得到了一个简单的关系,元素从开始的位置加上从结束的位置等于长度。^x中的 x是你自己算出来从长度中减去的值。

为什么不使用减号(-)来代替新的帽子(^)操作符呢?这主要与范围有关。同样,为了与 Python 和大多数行业保持一致,我们希望我们的范围在开始时是包含的,在结束时是独占的。你传递给一个范围应该一直到结束的索引是什么?在 C # 中,答案很简单: x..^0x到结束。在 Python 中,没有明确的索引可以给出: -0不起作用,因为它等于 0,第一个元素!因此,在 Python 中,必须完全关闭 end 索引以表示到达结束的范围: x..。如果范围的末尾是计算出来的,那么您需要记住要有特殊的逻辑,以防出现 0。在 x..-y中,y被计算出来,变成了 0。这是一个常见的滋扰和错误的来源。

最后,注意索引和范围是。NET/C # .它们的行为不与应用它们的内容相关,甚至不与索引器中使用的内容相关。你完全可以定义自己的索引器,它接受 Index,另一个接受 Range-我们将把这样的索引器添加到例如 Span。但是也可以使用接受范围的方法,例如。

我的回答

我认为这符合我们习惯使用的经典语法:

value[^1] == value[value.Length - 1]

如果它使用0,那么当两种语法并排使用时就会混淆。这样就有了 低一点认知负荷。

Python 等其他语言也使用同样的约定。