Я понимаю, что null
недоверчиво встречается в Scala, и что каждый должен всегда переносить необязательные значения в Option
(или "нулевой тип", если он доступен).
Преимущества очевидны: никогда не должно быть необходимости проверять значения null
, и полученный код будет более безопасным и приятным для чтения.
На практике, однако, ничто не мешает значению быть null
- правило не применяется компилятором и является скорее джентльменским соглашением. Это может легко нарушиться при взаимодействии с Java API, например.
Есть ли для этого наилучшая практика? Скажем, например, что мне нужно написать класс case Url
, а экземпляры этого класса можно создать из java.net.URI
:
object Url {
def apply(uri: URI): Url = Url(uri.getScheme, uri.getHost, uri.getRawPath)
}
case class Url(protocol: String, host: String, path: String) {
def protocol(value: String): Url = copy(protocol = value)
def host(value: String): Url = copy(host = value)
def path(value: String): Url = copy(path = value)
}
An URI
экземпляр может возвращать null
для getScheme
, getHost
и getRawPath
. Является ли это достаточным для защиты от них в методе apply(URI)
(например, с операторами require
)? Технически, чтобы быть полностью безопасным, было бы лучше защитить вспомогательные методы protocol
, host
и path
, а также конструктор, но это звучит как ужасно много работы и шаблона.
Является ли безопасным вместо этого защищать от API, которые, как известно, принимают/возвращают значения null
(URI
в нашем примере) и предполагают, что внешние вызывающие абоненты либо не пройдут значения null
, либо только сами винить, если они это делают?