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 языка программирования, проверяйте пользовательский ввод статически (если это возможно) (с помощью набора текста) или настолько громко, насколько это целесообразно во время выполнения (так называемое защитное программирование на интерфейсах, обращенных к потребителю). Что важно, документируйте или определите край, так что нет никаких сомнений относительно:
- Какой тип (значения) значения принимает данное свойство
- Какие диапазоны значений действительны для данного свойства.
- Как составной тип должен быть структурирован. Какие свойства должны / должны / могут присутствовать в агрегатном типе?
- Если это какой-то тип контейнера, сколько элементов может или должен содержать контейнер, и какие типы значений содержит контейнер?
- В каком порядке возвращаются свойства или экземпляры типа контейнера или агрегата?
- Какие побочные эффекты существуют при установке определенных значений и каковы побочные эффекты при чтении этих значений?