Является ли переменная с именем i неприемлемой?[закрыто]
-
02-07-2019 - |
Вопрос
Что касается соглашений об именовании переменных, следует ли называть итераторы i
или что-то более семантическое, например count
?Если вы не используете i
, - почему бы и нет?Если ты чувствуешь, что i
приемлемо ли, есть ли случаи итерации, когда ее не следует использовать?
Решение
Полагаю, это зависит от контекста.Если вы выполняете цикл по набору объектов в некоторой коллекции , то из контекста должно быть достаточно очевидно, что вы делаете.
for(int i = 0; i < 10; i++)
{
// i is well known here to be the index
objectCollection[i].SomeProperty = someValue;
}
Однако, если из контекста не сразу понятно, что именно вы делаете, или если вы вносите изменения в индекс, вам следует использовать имя переменной, которое более указывает на использование.
for(int currentRow = 0; currentRow < numRows; currentRow++)
{
for(int currentCol = 0; currentCol < numCols; currentCol++)
{
someTable[currentRow][currentCol] = someValue;
}
}
Другие советы
"я" означает "счетчик циклов" для программиста.В этом нет ничего плохого.
Вот еще один пример того, что совершенно нормально:
foreach (Product p in ProductList)
{
// Do something with p
}
Я обычно использую i, j, k для очень локализованных циклов (существуют только в течение короткого периода с точки зрения количества исходных строк).Для переменных, которые существуют в большей области исходного кода, я обычно использую более подробные имена, чтобы я мог видеть, для чего они предназначены, без обратного поиска в коде.
Кстати, я думаю, что соглашение об именовании для них пришло из раннего языка Fortran, где I была первой целочисленной переменной (A - H были числами с плавающей запятой)?
i
это, безусловно, приемлемо.Однако за один семестр я многому научился у своего преподавателя C ++, который отказался от кода, в котором не было описательного имени для каждой отдельной переменной.Простой акт присвоения всему описательных имен заставил меня усерднее думать о своем коде, и после этого курса я написал лучшие программы, не изучая C ++, а научившись всему давать названия. Код Завершен есть несколько хороших слов на эту же тему.
i это нормально, но что-то подобное - нет:
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
string s = datarow[i][j].ToString(); // or worse
}
}
Программисты часто непреднамеренно меняют местами буквы i и j в коде, особенно если у них плохое зрение или тема их Windows - "хот-дог".Для меня это всегда "запах кода" - довольно редко, когда это не облажается.
i настолько распространен, что он приемлем даже для людей, которые любят описательные имена переменных.
Что абсолютно неприемлемо (и является грехом в моей книге), так это использование i, j или k в любом другом контексте, кроме как в качестве целочисленного индекса в цикле....например ,
foreach(Input i in inputs)
{
Process(i);
}
"я", безусловно, приемлемо.Не уверен, какое обоснование мне нужно привести, но я использую его постоянно, и другие очень уважаемые программисты делают то же самое.
Социальная валидация, я думаю :)
Да, на самом деле это предпочтительнее, поскольку любой программист, читающий ваш код, поймет, что это просто итератор.
Какова ценность использования i вместо более конкретного имени переменной?Чтобы сэкономить 1 секунду или 10 секунд, а может быть, даже 30 секунд размышлений и набора текста?
Какова стоимость использования i?Может быть, ничего.Возможно, код настолько прост, что использование i вполне допустимо.Но, может быть, использование i заставит разработчиков, которые в будущем придут к этому коду, задуматься на мгновение: "что я здесь имею в виду?" Им придется подумать:"это индекс, количество, смещение, флаг?" Им придется подумать:"безопасно ли это изменение, правильно ли оно, освобожусь ли я к 1 часу?"
Использование i экономит время и интеллектуальные усилия при написании кода, но в конечном итоге может потребовать дополнительных интеллектуальных усилий в будущем или, возможно, даже привести к непреднамеренному появлению дефектов из-за неправильного понимания кода.
Вообще говоря, большая часть разработки программного обеспечения заключается в обслуживании и расширении, поэтому количество времени, затраченного на чтение вашего кода, значительно превысит количество времени, затраченного на его написание.
Очень легко выработать привычку использовать значимые имена везде, и как только у вас появится эта привычка, вам потребуется всего несколько секунд, чтобы написать код со значимыми именами, но тогда у вас будет код, который легче читать, понятнее и более очевидно корректен.
Я использую i для коротких циклов.
Причина, по которой это нормально, заключается в том, что я нахожу совершенно невероятным, что кто-то мог увидеть объявление типа iterator с инициализатором, а затем тремя строками позже утверждать, что неясно, что представляет переменная.Они просто притворяются, потому что решили, что "значимые имена переменных" должны означать "длинные имена переменных".
Причина, по которой я на самом деле это делаю, заключается в том, что я нахожу, что использование чего-то, не связанного с конкретной поставленной задачей, и что я бы использовал только в небольшой области, избавляет меня от беспокойства о том, что я могу использовать имя, которое вводит в заблуждение или двусмысленно, или когда-нибудь будет полезно для чего-то другого в более широкой области.Причина, по которой это "i", а не "q" или "count", - просто условность, заимствованная из математики.
Я не использую i, если:
- Тело цикла не маленькое, или
- итератор делает что угодно, кроме продвижения (или отступления) от начала диапазона до конца цикла:
мне не обязательно идти с шагом 1, если приращение является последовательным и четким и, конечно, может прекратиться до окончания iterand, но если оно когда-либо изменит направление или не будет изменено итерацией цикла (включая дьявольское использование iterator.insertAfter() в прямом цикле), я стараюсь не забывать использовать что-то другое.Это сигнализирует "это не просто тривиальная переменная цикла, следовательно, это может быть не тривиальный цикл".
Если "чем-то более семантическим" является "итератор", то нет причин не использовать i;это хорошо понятная идиома.
я думаю, что i полностью приемлем в ситуациях с циклом for.я всегда считал это довольно стандартным и никогда по-настоящему не сталкивался с проблемами интерпретации, когда i использовался в данном случае.циклы foreach становятся немного сложнее, и я думаю, что это действительно зависит от вашей ситуации.я редко, если вообще когда-либо использую i в foreach, только в циклах for, поскольку нахожу i слишком не описательным в этих случаях.для foreach я пытаюсь использовать сокращение от типа объекта, который зацикливается.например,:
foreach(DataRow dr in datatable.Rows)
{
//do stuff to/with datarow dr here
}
в любом случае, только мои 0,02 доллара.
Это поможет, если вы назовете его как-то, что описывает, через что он проходит.Но обычно я использую просто i.
Пока вы либо используете i для подсчета циклов, либо часть индекса, который изменяется от 0 (или 1 в зависимости от PL) до n, я бы сказал, что i в порядке.
В противном случае, вероятно, легко назвать i чем-то значимым, это больше, чем просто индекс.
Я должен отметить, что i и j также являются математическими обозначениями для матричных индексов.И обычно вы зацикливаетесь на массиве.Так что в этом есть смысл.
Конечно, до тех пор, пока вы используете его временно внутри простого цикла и очевидно, что вы делаете.Тем не менее, нет ли другого короткого слова, которое вы могли бы использовать вместо него?
i
широко известен как итератор цикла, так что на самом деле вы с большей вероятностью собьете с толку программистов по обслуживанию, если будете использовать его вне цикла, но если вы используете что-то более описательное (например filecounter
), это делает код приятнее.
Это зависит от обстоятельств.Если вы выполняете итерацию по какому-то определенному набору данных, то я думаю, имеет смысл использовать описательное имя.(например. filecounter
как и предполагал Дэн).
Однако, если вы выполняете произвольный цикл, то i
это приемлемо.Как описал мне это один напарник по работе - i
это соглашение, которое означает, что "эта переменная всегда изменяется только for
конструкция цикла.Если это неправда, не используйте i
"
Использование i, j, k для счетчиков ЦЕЛОЧИСЛЕННОГО цикла восходит к ранним дням FORTRAN.
Лично у меня с ними нет проблем, пока они являются ЦЕЛЫМИ числами.
Но потом я вырос на ФОРТРАНЕ!
у меня такое чувство, что концепция использование одной буквы прекрасно подходит для "простых" циклов, однако я давным-давно научился использовать двойные буквы, и это отлично сработало.
я спросил у похожий вопрос прошлая неделя и последующая являются частью мой собственный ответ:
// recommended style ● // "typical" single-letter style
●
for (ii=0; ii<10; ++ii) { ● for (i=0; i<10; ++i) {
for (jj=0; jj<10; ++jj) { ● for (j=0; j<10; ++j) {
mm[ii][jj] = ii * jj; ● m[i][j] = i * j;
} ● }
} ● }
на случай, если выгода не будет очевидна сразу:поиск в коде любой отдельной буквы приведет к обнаружению многих вещей, которые не являются то, что вы ищете.письмо i
встречается довольно часто в коде, где это не та переменная, которую вы ищете.
я делаю это таким образом по меньшей мере 10 лет.
обратите внимание, что многие люди прокомментировали, что любое из вышеперечисленных действий "уродливо"...
Я собираюсь пойти против течения и сказать "нет".
Для толпы, которая говорит "i понимается как итератор", это может быть правдой, но для меня это эквивалентно комментариям типа "Присвоите значение 5 переменной Y.Имена переменных, такие как comment, должны объяснять "почему", а не "как".
Чтобы использовать пример из предыдущего ответа:
for(int i = 0; i < 10; i++)
{
// i is well known here to be the index
objectCollection[i].SomeProperty = someValue;
}
Неужели так сложно просто использовать осмысленное имя вот так?
for(int objectCollectionIndex = 0; objectCollectionIndex < 10; objectCollectionIndex ++)
{
objectCollection[objectCollectionIndex].SomeProperty = someValue;
}
Конечно, (заимствованное) имя переменной ObjectCollection тоже довольно неудачно названо.