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

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

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

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

var apple;

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

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

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

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

Ответы [ 27 ]

0 голосов
/ 03 марта 2009

VB6

  • Ничего => "Нет значения."
  • Null => «Я не знаю, что это за значение» - то же, что DBNull.Value в .NET
0 голосов
/ 01 марта 2009

Вы всегда можете создать объект и назначить его тому же статическому полю, чтобы получить 2-й ноль.

Например, это используется в коллекциях, которые позволяют элементам быть нулевыми. Внутренне они используют private static final Object UNSET = new Object, который используется как неустановленное значение и, таким образом, позволяет хранить null s в коллекции. (Насколько я помню, инфраструктура коллекции Java называет этот объект TOMBSTONE вместо UNSET. Или это была среда коллекции Smalltalk?)

0 голосов
/ 26 февраля 2009

Для меня ноль означает отсутствие значения, и я стараюсь использовать его только для представления этого. Конечно, вы можете задать null столько значений, сколько захотите, точно так же, как вы можете использовать 0 или -1 для представления ошибок вместо их числовых значений. Придавать различные значения одному представлению может быть неоднозначно, поэтому я бы не рекомендовал это.

Ваши примеры могут быть закодированы как apple.isRefused () или! Apple.isValid () без особых усилий; в любом случае вам следует заранее определить, что является недопустимым яблоком, поэтому я не вижу выгоды от использования большего количества ключевых слов.

0 голосов
/ 26 февраля 2009
AppleInformation appleInfo;    
while (appleInfo is null)
{
    askForAppleInfo();
}

Apple apple = appleInfo.apple;
if (apple is null)
{
    sulk();
}
else
{
    eatApple(apple);
}

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

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

Если вы используете .NET 3.0+ и вам нужно что-то еще, вы можете попробовать Возможно Monad . Вы можете создавать любые типы «Maybe», которые вам нужны, и, используя синтаксис LINQ, обрабатывать их соответствующим образом.

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

Я думаю, что один NULL - это более низкий общий знаменатель для работы с базовым шаблоном

if thing is not NULL
  work with it
else
  do something else

В части «сделай что-нибудь другое» существует широкий диапазон возможностей: от «хорошо, забудь об этом» до попытки «получить вещь» где-то еще. Если вы просто не игнорируете что-то, что имеет значение NULL, вам, вероятно, нужно знать, почему «вещь» была NULL. Наличие нескольких типов NULL поможет вам ответить на этот вопрос, но возможных ответов множество, как указано в других ответах здесь. Отсутствующая вещь может быть просто ошибкой, может быть ошибкой при попытке ее получить, она может быть недоступна прямо сейчас и так далее. Чтобы решить, какие случаи применимы к вашему коду - что означает, что вы должны их обрабатывать - это зависит от домена. Поэтому лучше использовать механизм, определенный приложением, для кодирования этих причин, а не искать языковую функцию, которая пытается справиться со всеми из них.

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

Это потому, что Null - это артефакт языка, который вы используете, а не удобство для программиста. Он описывает естественное состояние объекта в контексте, в котором он используется.

...