Почему новый индекс оператора шляпы из функции вырезания массива в C # 8 не начинается с 0? - PullRequest
0 голосов
/ 08 января 2019

C # 8.0 представляет удобный способ нарезки массивов - см. официальный пост C # 8.0 .

Синтаксис для доступа к последнему элементу массива:

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

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

Мне интересно, почему индексирование для доступа к элементам в обратном направлении начинается с 1 вместо 0? Есть ли техническая причина для этого?

1 Ответ

0 голосов
/ 08 января 2019

Официальный ответ

Для лучшей наглядности вот комментарий от Мэдс Торгерсен , объясняющий это дизайнерское решение из сообщения в блоге C # 8 :

Мы решили следовать Python, когда дело доходит до арифметики начала и конца. 0 обозначает первый элемент (как всегда), а ^0 «длина», т. Е. Тот, который находится непосредственно с конца. Таким образом, вы получите простое отношение, где позиция элемента от начала плюс его позиция от конца равна длине. x в ^x - это то, что вы вычли бы из длины, если бы вы сделали математику самостоятельно.

Почему бы не использовать минус (-) вместо оператора новой шляпы (^)? Это в первую очередь связано с диапазонами. Опять же, в соответствии с Python и большей частью отрасли, мы хотим, чтобы наши диапазоны были включающими в начале, исключительными в конце. Какой индекс вы передаете, чтобы сказать, что диапазон должен идти до конца? В C # ответ прост: x..^0 идет от x до конца. В Python нет явного индекса, который вы можете дать: -0 не работает, потому что он равен 0, первый элемент! Поэтому в Python вы должны полностью отключить конечный индекс, чтобы выразить диапазон, идущий до конца: x... Если вычисляется конец диапазона, вам нужно помнить, чтобы иметь специальную логику на случай, если она достигнет 0. Как и в x..-y, где y было вычислено и получилось 0. Это распространенная неприятность и источник ошибок.

Наконец, обратите внимание, что индексы и диапазоны являются первыми типами классов в .NET / C #. Их поведение не связано с тем, к чему они применяются, или даже для использования в индексаторе. Вы можете полностью определить свой собственный индексатор, который использует индекс, и еще один, который принимает Range - и мы собираемся добавить такие индексаторы, например, к. Span. Но вы также можете иметь методы, которые принимают диапазоны, например.

Мой ответ

Я думаю, что это соответствует классическому синтаксису, к которому мы привыкли:

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

Если бы он использовал 0, было бы непонятно, когда два синтаксиса использовались бок о бок. Таким образом, когнитивная нагрузка ниже .

Другие языки, такие как Python, также используют то же соглашение.

...