Что такое магическое число и почему оно плохо? - PullRequest
478 голосов
/ 07 сентября 2008

Что такое магическое число?

Почему этого следует избегать?

Есть ли случаи, когда это уместно?

Ответы [ 15 ]

3 голосов
/ 07 сентября 2008

Я всегда использовал термин «магическое число» по-разному, как неясное значение, хранящееся в структуре данных, которое можно проверить как быструю проверку достоверности. Например, файлы gzip содержат 0x1f8b08 в качестве первых трех байтов, файлы классов Java начинаются с 0xcafebabe и т. Д.

Вы часто видите магические числа, встроенные в форматы файлов, потому что файлы могут быть отправлены довольно беспорядочно и теряют любые метаданные о том, как они были созданы. Однако магические числа также иногда используются для структур данных в памяти, таких как вызовы ioctl ().

Быстрая проверка магического числа перед обработкой файла или структуры данных позволяет заранее сигнализировать об ошибках, а не проходить весь путь через потенциально длительную обработку, чтобы объявить, что ввод был завершен.

3 голосов
/ 07 сентября 2008

Стоит отметить, что иногда вам нужны неконфигурируемые «жестко запрограммированные» числа в вашем коде. Существует ряд известных , включая 0x5F3759DF, который используется в оптимизированном алгоритме обратного квадратного корня.

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

1 голос
/ 12 августа 2013

А как насчет возвращаемых переменных?

Мне особенно сложно при реализации хранимых процедур .

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

int procGetIdCompanyByName(string companyName);

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

int procGetIdCompanyByName(string companyName, bool existsCompany);

Кстати, что он должен вернуть, если компании не существует? Хорошо: он установит existesCompany как false , но также вернет -1.

Другой вариант - сделать две отдельные функции:

bool procCompanyExists(string companyName);
int procGetIdCompanyByName(string companyName);

Итак, предварительным условием для второй хранимой процедуры является наличие компании.

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

Суть заключается в следующем: что вы думаете об использовании такого рода "магических чисел", которые относительно известны и безопасны, чтобы сказать, что что-то не удалось или что-то не существует?

1 голос
/ 07 сентября 2008

@ eed3si9n: Я бы даже предположил, что «1» - это магическое число. : -)

Принцип, связанный с магическими числами, заключается в том, что каждый факт, с которым работает ваш код, должен быть объявлен ровно один раз. Если вы используете магические числа в своем коде (например, пример длины пароля, который дал @marcio, вы легко можете в конечном итоге воспроизвести этот факт, и когда ваше понимание этого факта изменится, у вас возникнет проблема обслуживания.

0 голосов
/ 10 июня 2015

Еще одно преимущество извлечения магического числа в качестве константы дает возможность четко документировать деловую информацию.

public class Foo {
    /** 
     * Max age in year to get child rate for airline tickets
     * 
     * The value of the constant is {@value}
     */
    public static final int MAX_AGE_FOR_CHILD_RATE = 2;

    public void computeRate() {
         if (person.getAge() < MAX_AGE_FOR_CHILD_RATE) {
               applyChildRate();
         }
    }
}
...