Какая разница между типом опции и типом NULL?

В F # мантре, кажется, есть висцеральное избегание null, Nullable<T> и его ilk. Взамен мы должны использовать типы опций. Честно говоря, я действительно не вижу разницы.

  • Мое понимание типа опции F # заключается в том, что оно позволяет указать тип, который может содержать любые его нормальные значения, или None. Например, Option<int> позволяет использовать все значения, которые имеет int, помимо None.

  • Мое понимание типов с нулевым значением С# заключается в том, что он позволяет указать тип, который может содержать любые его нормальные значения, или null. Например, a Nullable<int> a.k.a int? позволяет использовать все значения, которые имеет int, помимо null.

Какая разница? Сделайте некоторые словарные замены с помощью Nullable и Option, null и None, и у вас в основном есть одно и то же. Какова вся суета над null о?

Ответ 1

Параметры F # являются общими, вы можете создать Option<'T> для любого типа 'T.

Nullable<T> - ужасно странный тип; вы можете применять его только к структурам, и хотя тип Nullable сам по себе является структурой, он не может применяться к самому себе. Поэтому вы не можете создать Nullable<Nullable<int>>, тогда как вы можете создать Option<Option<int>>. Они должны были сделать некоторую фреймворк, чтобы сделать эту работу для Nullable. В любом случае это означает, что для Nullables вы должны знать априорно, если тип является классом или структурой, и если это класс, вам нужно просто использовать null, а не Nullable. Это уродливая нечеткая абстракция; это основное значение, по-видимому, связано с взаимодействием с базой данных, поскольку, как я полагаю, это обычное дело с объектами "int или no value" для обработки в доменах базы данных.

По моему мнению, инфраструктура .Net - это всего лишь уродливый беспорядок, когда дело доходит до null и Nullable. Вы можете утверждать, что F # 'добавляет к беспорядку', имея Option, или что он спасает вас от беспорядка, предлагая избегать просто null/Nullable (за исключением случаев, когда это абсолютно необходимо для взаимодействия) и сосредоточиться на чистых решениях с Option s. Вы можете найти людей с обоими мнениями.

Вы также можете увидеть

Лучшее объяснение языков без нулевого значения

Ответ 2

Поскольку каждый тип ссылочного типа .NET может иметь это дополнительное, бессмысленное значение - независимо от того, имеет ли он значение null, существует вероятность, и вы должны его проверить, а потому, что Nullable использует null как свое представление "ничего" "Я думаю, что имеет смысл устранить всю эту странность (что делает F #) и требует возможности" ничего "быть явным. Option<_> делает это.

Ответ 3

  Какая разница?

F # позволяет вам выбрать, хотите ли вы, чтобы ваш тип был типом option, и, когда вы это делаете, предлагает вам проверить наличие None и делает явным присутствие или отсутствие None в типе.

С# заставляет каждый ссылочный тип разрешать null и не побуждает вас проверять наличие null.

Так что это просто разница по умолчанию.

Сделайте некоторую замену словаря с Nullable и Option, null и None, и у вас в основном будет то же самое. О чем весь этот шум вокруг нуля?

Как показали такие языки, как SML, OCaml и Haskell, удаление null удаляет множество ошибок времени выполнения из реального кода. В той степени, в которой первоначальный создатель null даже описывает это как "ошибку в миллиард долларов".

Ответ 4

Преимущество использования option заключается в том, что он делает явным, что переменная не может содержать значения, тогда как типы с нулевым значением оставляют ее неявной. Учитывая такое определение, как:

string val = GetValue(object arg);

Система типов не документирует, имеет ли значение val значение null, или что произойдет, если arg равно null. Это означает, что для проверки допущений вызывающего и вызываемого абонентов должны выполняться повторные проверки на границах функций.

Наряду с сопоставлением шаблонов код с использованием типов опций может быть проверен статически, чтобы гарантировать, что оба случая обрабатываются, например, следующий код приводит к предупреждению:

let f (io: int option) = function
| Some i -> i

Ответ 5

Ну, одно отличие состоит в том, что для Nullable<T> T может быть только структурой, которая резко сокращает использование.

Также не забудьте прочитать этот ответ: fooobar.com/questions/593040/...

Ответ 6

Как упоминается в OP, семантической разницы между использованием слов необязательный или обнуляемый при передаче необязательных типов нет.

Проблема со встроенной системой null становится очевидной, когда вы хотите выразить не -optional типы.

В С# все ссылочные типы могут быть null. Итак, если мы полагались на встроенный null для выражения необязательных значений, все ссылочные типы вынуждены быть необязательными... независимо от того, намеревался разработчик или нет. Разработчик не может указать non -optional ссылочный тип (до С# 8).

Таким образом, проблема не в семантическом значении null. Проблема в том, что null захвачен ссылочными типами.

Как разработчик С#, я хотел бы выразить опциональность, используя встроенную систему null. И это именно то, что С# 8 делает с обнуляемыми ссылочными типами.