Я понимаю, что 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, либо только сами винить, если они это делают?