В C#, когда вы "новый" массив, это выглядит так:
int[] someArray = new int[5];
Что я прочитал как:
int-array someArray = new int-array-of-size-5
Сегодня я случайно попытался создать массив таких массивов:
int[][] someArray = new int[][5];
Для меня это имело интуитивно понятный смысл - я бы прочитал это так:
int-array-array someArray = new int-array-array-with-size-5
Однако, получив запутанную ошибку и погуглив ее, я обнаружил, что вместо этого следует писать так:
int[][] someArray = new int[5][];
Для меня это не имеет смысла, потому что я прочитал это так:
int-array-array someArray = new int-array-with-size-5-array
Но я не создаю массив массивов целых 5 размеров, я создаю массив массивов целых чисел размером 5.
Каково основное обоснование дизайна синтаксиса? Как я собираюсь интерпретировать int[5][]
- какую ментальную модель я могу использовать, чтобы понять этот синтаксис?
new int[5][]
создать массив длины 5
целочисленных массивов.
новый массив размера 5, который может хранить массивы int.
@DmitryBychenko То, что вы говорите, имело бы смысл, если бы синтаксис был чем-то вроде new [5]int[]
.
@HansPassant То же, что и выше
@Clonkex: Сомневаюсь, что new [5]int[]
более читаем, чем new int[5][]
: фрагмент new [5]
выглядит подозрительно для меня: мы создаем - new
- но что? - а затем возьмите 5-й элемент [5]
, затем следует объявление массива int[]
@DmitryBychenko Полностью согласен. Я не говорю, что это должно быть как new [5]int[]
. Я просто говорю, что предложенная вами интерпретация имеет смысл только в этом случае.
@Dennis_E Спасибо за сообщение в блоге! Это безумие. Если серьезно, я не могу поверить, что они действительно решили сделать это таким образом. Итак, если я правильно понимаю, int[,][]
на самом деле не является одномерным массивом двумерных массивов, это двумерный массив одномерных массивов. Если это правда, то это массовое "WTF, зачем кому-то это делать??" момент для меня. До сих пор C# был для меня наиболее разумно спроектированным языком. По крайней мере, разыменование по-прежнему разумно, даже если объявление и инициализация - нет. Если вы можете резюмировать сообщение в блоге как ответ, я приму его; в противном случае я напишу свой собственный позже.
*"потому что разработчики C# хотели избежать странностей"" является субъективным, и на него нельзя ответить без самих разработчиков C#. Второй вопрос более законен. На самом деле ответ таков: спецификация типа не определяет длину массива как часть типа, поэтому нет смысла создавать массив из 5 целых чисел, это просто массив из массивов целых чисел, поэтому вы не можете создать такой массив, используя синтаксис new int[][5]
, потому что вторая пара скобки является частью типа, который не имеет длины.
@Charlieface Я полностью не согласен. Если я решу создать свою программу с определенным поведением, то это причина, по которой программа имеет такое поведение. Нет другой причины. Причина, по которой это так, заключается именно и исключительно в том, что разработчики C# решили, что так должно быть, чтобы сделать его более интуитивным для пользователей. Когда Эрик Липперт говорит, что это так, для меня этого достаточно. Помимо всего этого, отвечая на вопрос "почему так?" вполне возможно без команды разработчиков C#. Все, что вам нужно, это хороший источник для ссылки. Так работают 99% всех ответов. Так что да, не мог не согласиться больше, лол.
Правильно, но часто с такого рода вопросами в основном все сводится к тому, что «разработчики считали, что это будет лучше всего в то время», и нет записи этого разговора (иногда они сами не помнят). Сам Эрик Липперт часто говорит то же самое, и он участвовал в разработке спецификации C# более десяти лет назад. Часто ответ звучит так: «Так это всегда делалось (в C/C++)» или «ни у кого не было денег, чтобы вложить деньги, чтобы сделать это по-другому». Это просто очень субъективно, если у вас нет буквально точной записи разговоров. И извините, но "лол" - довольно насмешливое окончание комментария.
@Charlieface И тем не менее, сообщение в блоге датировано 2009 годом и кажется мне довольно четким. Я просто не понимаю, как это можно считать основанным на мнении. Очень редко бывает так, что никто не знает, почему функция языка была разработана именно так. Почти всегда есть причина, хорошая или нет.
Массив массивов
Как объясняется в этом сообщении в блоге, они хотели сохранить одинаковый порядок скобок при создании массива и при доступе к элементам массива. Попробую подытожить.
Когда вы обращаетесь к массиву следующим образом:
array[1][2]
это означает: возьмите массив с индексом 1 и получите элемент этого массива с индексом 2. Итак, при создании массива вы должны инициализировать его так:
new int[5][]
что означает объект, который содержит 5 массивов int. Странности не избежать. Либо странный порядок скобок при создании массива, либо странный порядок при доступе к массиву. Самый странный вариант, когда порядок оба раза разный.
Лично я думаю, что странностей можно полностью избежать, если не пытаться быть слишком умным в этом вопросе. Я не думаю, что это странно, что объявление/инициализация отменяется от разыменования. Это просто... нормально. int[]
будет массивом целых чисел, int[,][]
будет массивом двумерных массивов целых чисел. Сначала идет тип, затем индикатор того, что это массив этого типа. Но это то, что они решили сделать, так что это правильный ответ 👍 Спасибо!
Обратите внимание, что этот вопрос обсуждается на мета