Допустим, я покажу вам определение функции следующим образом:
val getPersonByName : (name : string) -> Person
Как вы думаете, что происходит, когда вы передаете name
человека, которого нет в хранилище данных?
- Выдает ли функция исключение NotFound?
- Возвращает ли оно ноль?
- Создает ли он человека, если он не существует?
За исключением чтения кода (если у вас есть доступ к нему), чтения документации (если кто-то был достаточно любезен, чтобы написать его) или просто вызова функции, у вас нет возможности узнать. И это в основном проблема с нулевыми значениями: они выглядят и действуют как ненулевые значения, по крайней мере, до времени выполнения.
Теперь предположим, что у вас есть функция с этой подписью:
val getPersonByName : (name : string) -> option<Person>
Это определение делает очень явным то, что происходит: вы либо вернете человека, либо не получите, и такая информация передается в типе данных функции. Обычно , у вас есть лучшая гарантия обработки обоих случаев типа параметра, чем потенциально нулевое значение.
Я бы сказал, что типы опций гораздо более доброжелательны, чем нули.