Почему у нас нет двух нулей? - PullRequest
30 голосов
/ 25 февраля 2009

Я часто задавался вопросом, почему языки с null, представляющими "нет значения" , не делают различий между пассивными "Я не знаю, что такое значение" и более напористый «Нет значения.» .

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

Я представляю себе следующее, где мы называем два состояния unknown и null:

var apple;

while (apple is unknown)
{
    askForApple();
}

if (apple is null)
{
    sulk();
}
else
{
    eatApple(apple);
}

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

Итак, если у нас может быть один null, почему у нас не может быть двух?

Ответы [ 27 ]

39 голосов
/ 25 февраля 2009

Разве это не достаточно плохо, что у нас есть один ноль?

34 голосов
/ 25 февраля 2009

В своем программировании я недавно применил практику разграничения «языка ноль» и «домена нуль».

«language null» - это специальное значение, предоставляемое языком программирования для выражения того, что переменная не имеет «значения». Он необходим в качестве фиктивного значения в структурах данных, списках параметров и возвращаемых значениях.

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

Программисты довольно часто используют язык null в качестве универсального домена null, но я обнаружил, что он делает код более процедурным (менее объектно-ориентированным) и более сложным для понимания.

Каждый раз, когда нужно получить значение NULL, спрашивайте себя: это NULL языка или NULL домена?

.
34 голосов
/ 25 февраля 2009

В большинстве языков программирования ноль означает «пустой» или «неопределенный». «Неизвестный», с другой стороны, это нечто иное. По сути «неизвестный» описывает состояние объекта. Это состояние должно быть откуда-то в вашей программе.

Взгляните на шаблон Null Object . Это может помочь вам достичь того, чего вы пытаетесь достичь.

11 голосов
/ 25 февраля 2009

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

var apple = Apple.Unknown;
while (apple == Apple.Unknown) {} // etc
11 голосов
/ 25 февраля 2009

javascript на самом деле имеет как null, так и undefined (http://www.w3schools.com/jsref/jsref_undefined.asp),, но многие другие языки не имеют.

7 голосов
/ 25 февраля 2009

Наличие значения:

  • Python: vars().has_key('variableName')
  • PHP: isset(variable)
  • JavaScript: typeof(variable) != 'undefined'
  • Perl: (variable != undef) или, если хотите: (defined variable)

Конечно, когда переменная не определена, она не равна NULL

3 голосов
/ 25 февраля 2009

Зачем останавливаться на двух?

Когда я брал базы данных в колледже, нам сказали, что кто-то (извините, не помню имя исследователя или бумаги) просмотрел кучу схем БД и обнаружил, что нуль имеет примерно 17 различных значений: еще не знаю "," не может быть известно "," не применяется "," нет "," пусто "," действие не выполнено "," поле не используется "и т. д.

3 голосов
/ 25 февраля 2009

Примечание null является приемлемым, но известным условием. Неизвестное состояние - это другое дело ИМО. Мой разговор с Дэном в разделе комментариев верхнего поста прояснит мою позицию. Спасибо, Дэн!

Вероятно, вы захотите узнать, был ли объект инициализирован или нет.

Actionscript имеет такую ​​вещь (null и undefined). Однако с некоторыми ограничениями.

См. документацию :

тип данных void

Тип данных void содержит только одно значение, неопределенное. В предыдущих версиях ActionScript значение undefined было значением по умолчанию для экземпляров класса Object. В ActionScript 3.0 значение по умолчанию для экземпляров объекта равно нулю. Если вы попытаетесь присвоить значение undefined экземпляру класса Object, Flash Player или Adobe AIR преобразуют значение в null. Вы можете назначить значение undefined только нетипизированным переменным. Нетипизированные переменные - это переменные, в которых отсутствует аннотация типа или используется символ звездочки (*) для аннотации типа. Вы можете использовать void только в качестве аннотации возвращаемого типа.

2 голосов
/ 25 февраля 2009

Что касается , почему у нас нет двух нулей, связано ли это с тем фактом, что исторически в C NULL был простым #define, а не отдельной частью языка вообще?

2 голосов
/ 25 февраля 2009

Тип Null является подтипом всех ссылочных типов - вы можете использовать null вместо ссылки на любой тип объекта - что сильно ослабляет систему типов. Он считается одним из исторически плохих идей его создателем , и существует только потому, что проверить, является ли адрес нулевым, легко реализовать.

...