Рекомендуется ли использовать однобуквенные переменные? [закрыто]

13

Рекомендуется ли использование однобуквенных переменных в Java? В фрагментах кода или учебниках вы часто их видите. Я не могу себе представить, что их рекомендуется поощрять, потому что это делает код относительно трудным для чтения, и я никогда не видел, чтобы они использовались в других языках программирования!

Уильям Эдвардс
источник
3
Да и нет. Полностью зависит от ситуации.
Завиор
1
Не всегда затрудняет чтение кода. Например, когда вы реализуете код, основанный на математических уравнениях, обычно имеет смысл использовать те же имена переменных, что и в уравнениях. (Комментарии указывают на статью / текст, где находятся исходные уравнения, или, если вы похожи на меня, вы иногда включаете для них код LaTeX.)
jamesqf

Ответы:

32

Правильно назвать вещи сложно. Очень тяжело. Если вы посмотрите на это с другой стороны, вы также можете принять это к значению, что правильно названные вещи важны. (В противном случае, почему бы вы потратили усилия, назвав его?)

Но иногда имена вещей просто не важны. Вот почему у нас есть такие вещи, как, например, анонимные функции («лямбды»): потому что иногда это просто не стоит называть вещи.

Существует множество примеров, когда подходят имена из одной буквы (или очень короткие):

  • i, j,k , lДля индексов цикла
  • k и v для ключа и значения в карте
  • n за номер (например, в Math.abs(n) )
  • a, b,c Для объектов произвольной (например , в max(a, b))
  • e для элемента в общем for each цикле
  • f для функции в функции высшего порядка
  • p для функции предиката в фильтре
  • T, T1, T2, ... для переменных типа
  • E для переменных типа, представляющих тип элемента коллекции
  • R для переменной типа, представляющей тип результата функции
  • exза исключением в catchпункте
  • op для операции на карте или в сложенном виде
  • добавление буквы sдля указания множественного числа, то есть набора (например, nsдля набора чисел xsи ysдля двух произвольных наборов общих объектов)

Я никогда не видел, чтобы они использовались на других языках программирования!

Они очень распространены почти во всех языках, которые я знаю (и, вероятно, также в тех, которые я не знаю). Haskell, F #, ML, Ruby, Python, Perl, PHP, C #, Java, Scala, Groovy, Boo, Nemerle, D, Go, C ++, C, вы называете это.

Йорг Миттаг
источник
5
-1 Использование однобуквенных имен переменных - ленивое программирование. Иногда это хорошо , чтобы быть ленивыми, но если вы получаете до kи lиндексов цикла, это слишком далеко (вы не должны иметь , что много вложенных циклов , чтобы начать с; извлечение их функции) . Лично я никогда не использую более одной 1-буквенной переменной для каждой функции, но я стреляю по 0.
BlueRaja - Дэнни Пфлугхофт
Также, lили lenиспользуется для длины и arrдля массива (например:) for(var i=0; l=arr.length; i<l; i++). Кроме того, fnможет использоваться вместо f, когда вы ссылаетесь на функцию.
Исмаэль Мигель
4
@ BlueRaja-DannyPflughoeft Я предпочитаю считать это эффективным программированием. Йорг, вероятно, мог бы остановиться на том, когда уместны отдельные буквы, а не только где, но, честно говоря, я думаю, что большинство программистов проводят черту иначе. Что касается индексов цикла, я могу утверждать, что любой код, где индексам не нужны имена с семантическим значением, достаточно прост, чтобы оправдать многоуровневое вложение над ненужным извлечением. Их также можно использовать в отдельных циклах, чтобы избежать возможных проблем с областями видимости, которые поднимает Нельсон .
Лилиенталь
2
@Lilienthal: код должен быть эффективным для чтения, а не эффективным для записи. Обычно они одно и то же, но не всегда, как в этом случае.
BlueRaja - Дэнни Пфлюгофт
@ BlueRaja-DannyPflughoeft Не во всех программах нет, но я не вижу ничего плохого в предложениях Йорга. Как сказал Киллиан : «Все, что дольше, не может сделать семантику более очевидной, но на чтение уходит гораздо больше времени». Но это, вероятно, во многом вопрос личных предпочтений и стиля.
Лилиенталь
20

Если ваш цикл ничего не делает, но использует переменную для подсчета

  for(int i = 0; i < 10; i++) {
     System.out.println("Stop it! I really mean it!!");
  }

тогда да, это лучшее имя, которое вы можете использовать. Все, что дольше, не может сделать семантику более очевидной, но на чтение уходит гораздо больше времени.

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

for(int door = 0; door < 3; door++) {
  int reward = gauge(door);
  if(reward > max) {
    max = reward;
    best = door;
  }
}

Если ваша переменная используется в методе, ее имя должно быть длиннее; если он используется в масштабах всего класса, его имя должно быть самоочевидным, иначе это почти наверняка уменьшит ясность вашего кода.

Короче говоря, чем больше область действия переменной, тем длиннее должно быть ее имя.

Килиан Фот
источник
Честно говоря, я дошел до того, что не буду использовать имена однозначных переменных, точка. Я пытаюсь использовать имена, которые объясняют использование, даже для счетчиков. indexНапример, я бы использовал переменную с именем при итерации по массиву.
Майкл
13
@Michael: На мой взгляд, язык программирования - это собственный язык, а не английский. И на этом языке iэто правильное слово с точно определенным значением, а именно «индекс, о котором вам не нужно слишком беспокоиться». Но я думаю, что это вопрос знакомства. Если вы много читаете на Haskell, вы привыкнете читать mкак монаду , fкак функтор , xкак некоторый объект , xsкак список xs и так далее.
Йорг Миттаг
2
Просто действительно огромное предостережение. Однобуквенные имена переменных допустимы, только если язык имеет правильную область видимости переменных. Вы, очевидно, спросите: «На каком языке нет правильной оценки?». Ну, мне потребовалось три часа, чтобы понять, что JavaScript не включает переменные в цикле FOR. Попробуйте это с помощью цикла for внутри цикла for с тем же именем переменной. Это взорвет ваш разум.
Нельсон
@ Нельсон: Этот вопрос и ответ о Java. Очевидно, что разные языки могут иметь несколько разные соображения. (JavaScript не является тем же языком, что и Java.)
ruakh,
Я полностью поддерживаю однобуквенные имена переменных, когда они имеют больше смысла, но я не согласен, что iэто «лучшее имя, которое вы можете использовать» для цикла, который использует переменную только для подсчета. В этом случае я бы предпочел countиспользовать имя переменной: понятно. for (int count = 0; count < 10; count++)или while (count--).
Тодд Леман
4

Читая код в ответе Килиана, я не думаю, что «есть цикл, и есть переменная, и она имеет тип int, и у нее есть имя, и имя i, и оно инициализируется 0,. .. ". Я просто думаю «петля ...», где три точки обозначают неважные детали, о которых я даже не думаю. По моему мнению программиста, эта переменная на самом деле не существует, это просто артефакт, который я должен напечатать, например, for (;;) {}, который делает ее цикличной.

Поскольку эта переменная даже не существует в моей голове, почему я должен дать ей имя, помимо того, что абсолютно необходимо?

gnasher729
источник
Я должен добавить, что в такой конструкции я часто испытываю желание использовать не даже i, но _для явно бессмысленной переменной. Но не все знакомы с Прологом, и это, вероятно, привлечет больше внимания, чем устранит.
Килиан Фот
Вы также должны рассмотреть, как переменная используется внутри цикла, а не только в for (...)заголовке.
@KilianFoth: я так думаю, он также используется в Haskell, ML, F # и Scala. И в Ruby, несмотря на то, что он _является легальным идентификатором, как и любой другой, было недавнее изменение, согласно которому неиспользуемые локальные переменные с именами _(или начинающиеся с _) не генерируют предупреждение «неиспользуемая локальная переменная», хотя Ruby обычно предупреждает о них.
Йорг Миттаг
-1

Если вы ссылаетесь на буквы i, j, k как на индексы внутри цикла, это обычная практика в Java и других языках программирования. Хотя там, вероятно, лучше использовать для каждого цикла стиля, такого как

for(User user: users) {
  doSomethingWithTheUser(user);
}

вместо того

for(int i=0; i<users.size(); i++) {
  doSomethingWithTheUser(users.get(i));
}

В Java этот стиль зацикливания появился только недавно. Это может быть причиной того, что вы заметили это больше для Java, так как зацикливание на индексах раньше было наиболее распространенным способом зацикливания над массивом или списком.

Есть несколько других случаев, когда отдельные буквы могут быть подходящими, например, при реализации математической функции, где отдельные буквы, такие как n, x или y, уже могут быть общими. Но в целом, нет, назовите ваши переменные как-то значащими.

Ник
источник
5
«В Java такой стиль зацикливания появился совсем недавно» ... как, десять лет назад? ( Java 5 была выпущена в 2004 году )
меритон
1
Да, это довольно недавно. Нет, я не старый. Молчи. Чертовы дети сорвались с моей лужайки. До Java 5 было еще много унаследованных Java-приложений. И еще больше программистов на Java, которые изучили язык на Java 1.4 и отказываются обновлять свою работу. И все же еще больше примеров кода в Интернете, относящихся к началу 2000-х годов (да, у нас тогда был Интернет; мы просто назвали его Web 2.0).
Ник