Какая разница между типом опции и типом 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 делает с обнуляемыми ссылочными типами.