null
Использование зависит от приложения / языка
В конечном счете, выбор того, использовать ли его null
в качестве допустимого значения приложения или нет, во многом определяется вашим приложением и языком программирования / интерфейсом / гранью.
На фундаментальном уровне я бы рекомендовал использовать разные типы, если есть разные классы значений. null
может быть вариант, если ваш интерфейс позволяет это, и есть только два класса свойства, которое вы пытаетесь представить. Пропуск свойства может быть вариантом, если ваш интерфейс или формат позволяет это. Новый агрегатный тип (класс, объект, тип сообщения) может быть другой опцией.
Для вашего примера строки, если это на языке программирования, я бы задал себе пару вопросов.
- Планирую ли я добавлять будущие типы значений? Если так, то
Option
, вероятно, будет лучше для вашего дизайна интерфейса.
- Когда мне нужно проверять звонки потребителей? Статически? Динамически? До? После? Вообще? Если ваш язык программирования поддерживает это, используйте преимущества статической типизации, поскольку это позволяет избежать объема кода, который вы должны создать для проверки.
Option
вероятно, лучше всего подходит для этого случая, если ваша строка не имеет значения NULL. Тем не менее, вам, вероятно, все null
равно придется проверять пользовательский ввод на наличие строкового значения, поэтому я бы, вероятно, отложил вопрос до первой строки: сколько типов значений я хочу / буду представлять.
- Означает ли
null
ошибка программиста в моем языке программирования? К сожалению, null
часто это значение по умолчанию для неинициализированных (или неявно инициализированных) указателей или ссылок в некоторых языках. Является ли null
значение приемлемым в качестве значения по умолчанию? Это безопасно в качестве значения по умолчанию? Иногда null
указывает на освобожденные значения. Должен ли я предоставить потребителям моего интерфейса указание этих потенциальных проблем с управлением памятью или инициализацией в их программе? Что такое режим отказа такого звонка перед лицом таких проблем? Находится ли вызывающий абонент в том же процессе или потоке, что и мой, чтобы такие ошибки представляли высокий риск для моего приложения?
В зависимости от ваших ответов на эти вопросы, вы, вероятно, сможете определить, подходит ли null
вам ваш интерфейс.
Пример 1
- Ваше приложение критично для безопасности
- Вы используете какой-либо тип инициализации кучи при запуске, и
null
это возможное строковое значение, возвращаемое после неудачной попытки выделить место для строки.
- Существует вероятность того, что такая строка попадает в ваш интерфейс
Ответ: null
вероятно, не подходит
Обоснование: null
в этом случае фактически используется для указания двух разных типов значений. Первое может быть значением по умолчанию, которое пользователь вашего интерфейса может захотеть установить. К сожалению, второе значение - это флаг, указывающий, что ваша система работает неправильно. В таких случаях вы, вероятно, захотите потерпеть неудачу настолько безопасно, насколько это возможно (что бы это ни значило для вашей системы).
Пример 2
- Вы используете структуру C, которая имеет
char *
член.
- Ваша система не использует распределение кучи, и вы используете проверку MISRA.
- Ваш интерфейс принимает эту структуру в качестве указателя и проверяет, что структура не указывает на
NULL
- Стандартное и безопасное значение
char *
члена для вашего API может быть указано одним значением:NULL
- После инициализации структуры вашего пользователя вы хотели бы предоставить пользователю возможность не явно инициализировать
char *
элемент.
Ответ: NULL
может быть уместным
Обоснование: существует небольшая вероятность того, что ваша структура пройдет NULL
проверку, но не будет инициализирована. Однако ваш API может быть не в состоянии учесть это, если у вас нет какой-либо контрольной суммы для значения структуры и / или проверки диапазона адреса структуры. Линтеры MISRA-C могут помочь пользователям вашего API, помечая использование структур перед их инициализацией. Однако, что касается char *
члена, если указатель на структуру указывает на инициализированную структуру, NULL
это значение по умолчанию для неопределенного члена в инициализаторе структуры. Следовательно, NULL
может служить безопасным значением по умолчанию для char *
члена структуры в вашем приложении.
Если бы он был в интерфейсе сериализации, я бы задал себе следующие вопросы о том, использовать ли null в строке.
- Является
null
показатель потенциальной клиентской стороны ошибки? Для JSON в JavaScript это, вероятно, нет, поскольку null
не обязательно используется как указание на ошибку выделения. В JavaScript это используется как явное указание на отсутствие объекта в ссылке, которая будет установлена проблематично. Однако существуют не-javascript-парсеры и сериализаторы, которые отображают JSON null
на нативный null
тип. Если это так, то возникает вопрос о том, null
нормально ли использование родного языка для вашей конкретной комбинации языка, анализатора и сериализатора.
- Влияет ли явное отсутствие значения свойства более чем на одно значение свойства? Иногда a
null
фактически указывает, что у вас полностью новый тип сообщения. Для ваших потребителей формата сериализации может быть проще указать совершенно другой тип сообщения. Это гарантирует, что их проверка и логика приложения могут иметь четкое разделение между двумя различиями сообщений, которые предоставляет ваш веб-интерфейс.
Генеральный Совет
null
не может быть значением ребра или интерфейса, который его не поддерживает. Если вы используете что-то очень необычное в наборе значений свойств (например, JSON), попробуйте использовать какую-либо форму схемы или проверку в программном обеспечении конечного пользователя (например, JSON Schema ), если можете. Если это API языка программирования, проверяйте пользовательский ввод статически (если это возможно) (с помощью набора текста) или настолько громко, насколько это целесообразно во время выполнения (так называемое защитное программирование на интерфейсах, обращенных к потребителю). Что важно, документируйте или определите край, так что нет никаких сомнений относительно:
- Какой тип (значения) значения принимает данное свойство
- Какие диапазоны значений действительны для данного свойства.
- Как составной тип должен быть структурирован. Какие свойства должны / должны / могут присутствовать в агрегатном типе?
- Если это какой-то тип контейнера, сколько элементов может или должен содержать контейнер, и какие типы значений содержит контейнер?
- В каком порядке возвращаются свойства или экземпляры типа контейнера или агрегата?
- Какие побочные эффекты существуют при установке определенных значений и каковы побочные эффекты при чтении этих значений?