Я помню много лет назад, когда я был в школе, один из моих учителей информатики учил нас, что было лучше проверить на 'верность' или 'равенство' условия а не отрицательного материала как 'неравенство'.
Позвольте мне уточнить - Если часть условного кода может быть записана путем проверки, является ли выражение TRUE или FALSE, мы должны проверить 'верность'.
Пример: Обнаружение, нечетно ли число - оно может быть сделано двумя способами:
if ( num % 2 != 0 )
{
// Number is odd
}
или
if ( num % 2 == 1 )
{
// Number is odd
}
(См. отмеченный ответ для лучшего примера.)
Когда я начинал кодировать, я знал это num % 2 == 0
подразумевает, что число даже, таким образом, я просто поместил a !
там, чтобы проверить, нечетно ли это. Но он был похож, 'Не проверяют НЕ условия. Имейте практику проверки 'верности или 'равенство' условий каждый раз, когда возможный'. И он рекомендовал, чтобы я использовал вторую часть кода.
Я не за или против ни одного, но я просто хотел знать - какое значение это имеет? Не отвечайте, 'Что технически вывод будет тем же' - все мы знаем это. Действительно ли это - общая практика программирования или является этим его собственная практика программирования, которую он проповедует другим?
Примечание: Я использовал C#/C ++ синтаксис стиля ни по какой причине. Мой вопрос одинаково применим при использовании IsNot
, <>
операторы в VB и т.д. Так удобочитаемость'!' оператор является только одной из проблем. Не проблема.
Проблема возникает, когда позже в проекте добавляются дополнительные условия - один из проектов, над которыми я сейчас работаю, постоянно собирал условия с течением времени (затем некоторые из этих условий были перемещены в теги struts, а некоторые - в JSTL ...) - один негатив прочитать несложно, но 5+ - это кошмар, особенно когда кто-то решает реорганизовать и свести на нет все это. Может быть, в новом проекте вы напишете:
if (authorityLvl!=Admin){
doA();
}else{
doB();
}
Вернитесь через месяц, и он станет таким:
if (!(authorityLvl!=Admin && authorityLvl!=Manager)){
doB();
}else{
doA();
}
Все еще довольно просто, но это займет еще секунду.
Теперь дайте ему еще 5–10 лет, чтобы он гнил.
(x% 2! = 0), конечно, не проблема, но, возможно, лучший способ избежать описанного выше сценария - научить учащихся не использовать отрицательные условия в качестве общего правила в надежде что они рассудят, прежде чем это сделают - потому что просто сказать, что это может стать проблемой обслуживания, вероятно, не будет достаточной мотивацией.
В качестве дополнения, лучший способ написать код:
userHasAuthority = (authorityLvl==Admin);
if (userHasAuthority){
doB();
else{
doA();
}
Теперь будущие программисты с большей вероятностью просто добавят «|| authorLvl == Manager», userHasAuthority легче превратить в метод, и даже если условное реорганизовано, у него будет только один минус. Более того, никто не добавит дыру в безопасности приложения, допустив ошибку при применении закона Де Моргана.
Мне говорили, что это связано с тем, насколько "заметен" символ ping (!) при беглом чтении.
Если кто-то привычно "бегло читает" код - возможно, потому, что считает свою обычную скорость чтения слишком медленной, - то !
может быть легко пропущен, что приведет к критическому непониманию кода.
С другой стороны, если человек действительно постоянно читает весь код, то проблемы нет.
Два очень хороших разработчика, с которыми я работал (и которых очень уважаю), каждый из них напишет == false
вместо того, чтобы использовать !
по схожим причинам.
Ключевой фактор, на мой взгляд, заключается не столько в том, что работает для вас (или меня!), сколько в том, что работает для того, кто поддерживает код. Если код никогда не будет виден или поддерживаться кем-то еще, следуйте своей личной прихоти; если код должен поддерживаться другими, лучше придерживаться середины пути. Небольшой (тривиальный!) компромисс с вашей стороны сейчас, может спасти кого-то другого от недели отладки позже.
Обновление: При дальнейшем рассмотрении я бы предположил, что выделение условия в отдельную предикатную функцию обеспечит еще большую удобность:
if (isOdd(num))
{
// Number is odd
}
Вы все еще должны быть осторожны с такими вещами, как эта:
if ( num % 2 == 1 )
{
// Number is odd
}
Если num отрицательно и нечетно, то в зависимости от языка или реализации num % 2 может быть равно -1. В связи с этим, нет ничего плохого в проверке на ложность, если это упрощает хотя бы синтаксис проверки. Кроме того, использование !=, на мой взгляд, более понятно, чем просто !-, так как ! может слиться со скобками.
Чтобы проверить только истинность, нужно сделать так:
if ( num % 2 == 1 || num % 2 == -1 )
{
// Number is odd
}
Это просто пример. Суть в том, что если использование отрицания позволяет сократить количество проверок или сделать синтаксис проверок ясным, то, несомненно, следует использовать именно этот способ (как в приведенном выше примере). Запирание себя на проверку истинности не сделает ваше условие более читабельным.
Я не соглашусь с вашим старым профессором - проверка на условие НЕ - это нормально, если вы проверяете конкретное условие НЕ. Это действительно соответствует его критериям: вы должны проверить, ИСТИНА ли то, что значение НЕ является чем-то.
Я понимаю, что он имеет в виду - в большинстве случаев истинные условия будут на порядок меньше по количеству, чем условия НЕ, поэтому их легче проверить, поскольку вы проверяете меньший набор значений.
На самом деле очень косвенная проблема. Однако одним из недостатков проверки в этом смысле является то, что она работает только для двоичных сравнений. Если бы вы, например, проверяли какое-то свойство троичной системы счисления, вы были бы ограничены.
Я помню, что слышал то же самое на своих занятиях. Я думаю, что более важно всегда использовать более интуитивное сравнение, а не всегда проверять положительное условие.