Подтвердить что ты не робот

Что мы будем делать без NULL?

Я когда-то читал, что наличие нулевых типов - это абсолютное зло. Я полагаю, что это было в статье, написанной тем человеком, который их создал (в Аде?). Я верю, что это статья

Во всяком случае, так что, если по умолчанию язык, такой как С#, использует непустые типы? Как бы вы заменили некоторые общие идиомы на С# или Ruby или на любой другой общий язык, где null является приемлемым значением?

4b9b3361

Ответ 1

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

Например, все непримитивные типы Java (и все ссылочные типы С#) имеют значение NULL. Зачем? Мы можем идти туда и обратно, но в конечном счете, я готов поспорить, что ответ сводится к "это было легко". Для языка Java не существует ничего, что требует широкой нулеустойчивости. Ссылки на С++ предлагают прекрасный пример того, как изгнать нули на уровне компилятора. Конечно, С++ имеет гораздо более уродливый синтаксис, который Java явно пыталась свернуть, поэтому некоторые хорошие функции оказались на режущем столе рядом с плохим.

Нервные типы значений в С# 2.0 предложили шаг в правильном направлении - развязать нулеумие от семантики несвязанного типа или, что еще хуже, детали реализации CLR, но при этом все еще отсутствует способ сделать обратное с ссылочными типами. (Кодовые контракты велики и все, но они не встроены в систему типов, как мы обсуждаем здесь.)

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

Чтобы ответить на ваш вопрос: запрет нулей на современном языке, оптовый, был бы столь же глупым, как так называемая "ошибка в миллиард долларов". Существуют допустимые конструкторы программирования, в которых нули имеют приятные параметры: необязательные параметры, любой тип расчета по умолчанию/резервного копирования, где оператор coalesce приводит к краткому коду, взаимодействию с реляционными базами данных и т.д. Заставляя себя использовать дозорные значения, NaN и т.д. "лечение" намного хуже, чем болезнь.

Тем не менее, я предварительно соглашусь с выражением, выраженным в цитате, до тех пор, пока я могу уточнить, чтобы соответствовать моему собственному опыту:

  • количество ситуаций, в которых нулевые значения желательны, меньше, чем думают большинство людей.
  • после того, как вы вводите нули в библиотеку или кодировку, это много сложнее избавиться от них, чем добавлять их. (так что не позволяйте младшим программистам делать это по прихоти!)
  • масштабируемый масштаб ошибок с переменной продолжительностью жизни
  • Соответствует # 3: раннее раннее

Ответ 2

Мы будем использовать типы опций для (очень) немногих мест, где допустимое нулевое значение действительно желательно, и у нас будет много менее непонятных ошибок, поскольку любая ссылка на объект будет гарантированно указывать на действительный экземпляр соответствующего типа.

Ответ 3

Haskell - мощный язык, который не имеет понятия nullity. В принципе, каждая переменная должна быть инициализирована на ненулевое значение. Если вы хотите представить "необязательную" переменную (переменная может иметь значение, но она может и не быть), вы можете использовать специальный тип "Maybe".

Легче реализовать эту систему в Haskell, чем С#, потому что данные неизменны в Haskell, поэтому на самом деле нет смысла иметь нулевую ссылку, которую вы позже заселяете. Однако в С# последняя ссылка в связанном списке может иметь нулевой указатель на следующую ссылку, которая заполняется, когда список расширяется. Я не знаю, как выглядит процедурный язык без нулевых типов.

Кроме того, обратите внимание, что многие вышеописанные люди предлагают предлагать замену нулей типами логических "ничего" (999-999-9999, "NULL" и т.д.). Эти значения на самом деле ничего не решают, потому что проблема людей с нулями заключается в том, что они являются особым случаем, но люди забывают кодировать для особого случая. Поскольку значение типа ничего не имеет значения, люди STILL забывают закодировать специальный случай, но они избегают ошибок, которые ловят эту ошибку, что плохо.

Ответ 5

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

Это будет эффективно реализация языка шаблона NullObject на весь язык: http://en.wikipedia.org/wiki/Null_Object_pattern Таким образом, он действительно не избавляется от нулевых объектов, он просто не позволяет им быть особыми случаями, которые необходимо обрабатывать как таковые.

Ответ 6

Tcl - это один язык, который не только не имеет понятия null, но и где само понятие null не согласуется с ядром языка. В tcl мы говорим: "все это строка". То, что это на самом деле означает, это tcl имеет строгую семантику значений (которая просто имеет значение по умолчанию для строк).

Итак, что используют tcl-программисты для представления "no-data"? В основном это пустая строка. В некоторых случаях, когда пустая строка может представлять данные, ее обычно один из:

  • Использовать пустую строку в любом случае - в большинстве случаев это не имеет никакого значения для конечного пользователя.

  • Используйте значение, которое, как вы знаете, не будет существовать в потоке данных - например, строка "_NULL_" или номер 9999999 или мой любимый байт NUL "\0".

  • Используйте структуру данных, обернутую вокруг значения. Самый простой - это список (какие другие языки называют массивами). Список одного элемента означает, что существует значение, нулевой элемент означает null.

  • Проверка наличия переменной - [info exists variable_name].

Интересно отметить, что Tcl не является единственным языком со строгой семантикой значений. C также имеет строгую семантику значений, но семантика значений по умолчанию просто является целыми числами, а не строками.

О, почти забыл еще один:

В некоторых библиотеках используется вариант номер 2, который позволяет пользователю указать, что такое заполнитель для "нет данных". В основном это позволяет указать значение по умолчанию (и если вы не используете значение по умолчанию, по умолчанию оно равно пустой строке).

Ответ 7

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

Если язык просто потребовал бы, чтобы любой указательный доступ был проверен или преобразован в непустой тип сначала, 99% ошибок, связанных с нулем, исчезнут. Например. в С++

void fun(foo *f)
{
    f->x;                  // error: possibly null
    if (f)              
    {
        f->x;              // ok
        foo &r = *f;       // ok, convert to non-nullable type
        if (...) f = bar;  // possibly null again
        f->x;              // error
        r.x;               // ok
    }
}

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

Ответ 8

Реально, на любом мощном языке программирования, который позволяет в первую очередь указывать указатели или ссылки на объекты, будут ситуации, когда код сможет получить доступ к указателям, которые не выполняли на них код инициализации. Возможно, можно гарантировать, что такие указатели будут инициализированы некоторым статическим значением, но это не кажется очень полезным. Если у машины есть общее средство захвата доступа к неинициализированным переменным (будь то указатели или что-то еще), это лучше, чем специальные указатели нулевого значения, но в остальном самые большие ошибки, связанные с ошибкой, встречаются в реализациях, которые допускают арифметику с нулевыми указателями, Добавление 5 в (char *) 0 не должно давать указатель на адрес 5; он должен вызывать ошибку (если это необходимо для создания указателей на абсолютные адреса, должны быть некоторые другие способы сделать это).

Ответ 9

Что бы мы сделали без NULL? Придумайте это!:-) Вам не обязательно быть ученым-ракетом, чтобы использовать 0, если вы ищете значение указателя внутри диапазона, чтобы на самом деле не указывать указатель.

Ответ 10

Мы используем либо

  • Дискриминаторы. Дополнительный атрибут или флаг или индикатор, указывающий, что значение "null" и должно игнорироваться.

  • Домены, специфичные для домена. Конкретное значение - в разрешенном домене, которое интерпретируется как "игнорировать это значение". Например, номер социального страхования 999-99-9999 может быть нулевым значением, специфичным для домена, которое говорит, что SSN либо неизвестно, либо не применимо.

Ответ 11

Мы создали бы всевозможные странные конструкции, чтобы передать сообщение об ошибке "недействительным" или "не быть там", как видно из других ответов. Сообщение, которое null может передать очень хорошо.

  • Образец нулевого объекта имеет свои недостатки, так как я объяснил здесь.
  • Нулевые значения для домена. Это заставляет вас проверять магические числа, что плохое.
  • Обертки коллекции, где пустая коллекция означает "нет значения". Обертки с нулевым будут лучше, но это не сильно отличается от проверки на null или с использованием шаблона Null Object.

Лично я бы написал некоторый препроцессор С#, который позволяет мне использовать null. Затем это будет отображаться для некоторого объекта dynamic, который выдает NullReferenceException всякий раз, когда на него вызывается метод.

Еще в 1965 году нулевые ссылки могли выглядеть как ошибка. Но теперь, со всеми инструментами анализа кода, которые предупреждают нас о нулевых ссылках, нам не нужно так беспокоиться. С точки зрения программирования null является очень ценным ключевым словом.