小编典典

为什么 C# 8 数组切片功能中的新帽子运算符索引不从 0 开始?

all

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 开始?这有技术原因吗?


阅读 44

收藏
2022-08-20

共1个答案

小编典典

官方回答

为了更好地了解,这里是 Mads Torgersen的评论,解释了 C# 8
博客文章
中的这个设计决定:

当涉及到从头到尾的算术时,我们决定遵循0Python指定第一个元素(一如既往),以及^0“长度”元素,即紧随其后的元素结尾。这样你就得到了一个简单的关系,一个元素从开始的位置加上它从结束的位置等于长度。x如果你自己算算^x的话,你会从长度中减去的。

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

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

我的答案

我认为这是为了匹配我们习惯的经典语法:

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

如果它使用 0,当这两种语法并排使用时会造成混淆。这样,它的认知负荷 较低。

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

2022-08-20