Как правильно использовать force unwrap?
Возникла дисскусия насчет того, что force unwrap нужно избегать практически всегда когда это возможно, но мое мнение, такое, что force unwrap можно (и даже нужно) ипользовать там где ты уверен (или хочешь показать, что ты не ожидаешь там null), то есть по моей теории optional (nullable) vars и ? сделаны не для того, чтоб бездумно лепить его везде где есть такая возможность.
Допустим такой пример
class TestDeleteIt {
var someImplementation: SomeImplementation? = null
init {
createImplementation()
startQuery()
}
fun createImplementation() {
someImplementation = SomeImplementation()
}
fun releaseImplementation() {
someImplementation?.let {
it.releaseRes()
}
someImplementation = null
}
private fun startQuery() {
someImplementation!!.doQuery()
}
}
То есть допустим у меня есть какой то обьект который может релизиться и создаваться и есть метод startQuery() в котором я точно не ожидаю, что этот обьект будет null и таким образом я хочу показать, что в этой строчке я ожидаю, что этот обьект точно инициализирован согласно моей логике, то есть я точно даю понять, что тут обьект уже готов и нет там вопроса, а если он может быть null или нет.
Кто что думает на этот счет и есть ли какие то ресурсы где можно почитать про это, своего рода best practices... Вот что то на подобии того, что написано здесь в последних строчках
https://agrawalsuneet.github.io/blogs/safe-calls-vs-null-checks-in-kotlin/
But if you are sure that the var property value is not null use !! instead of ?.
P.S. может пример не до конца верно отражает суть, но я надеюсь, что идея понятна:)
Ответы (2 шт):
конечно, вы можете обернуть ваш код с проверкой на null или через ?.let{} чтобы сделать его безопасным, но порой лучше получить словить ошибку, чем неожиданное поведение.
на самом деле, все зависит от принятого code-style и от ситуаций.
p.s. я вот сам задумался о том, чтобы написать экстеншн для действий с Nullable переменными. если переменная не нулл - выполнить действие. а если нулл, хотя уверен, что ей не должны быть - вывести в лог ошибку.
Чтобы не нарушать принцип fail-fast, но при этом получить достаточно осмысленное сообщение в случае ошибки, используйте стандартную функцию checkNotNull или requireNotNull, например:
val value: String? = getValue()
checkNotNull(value) { "Something went wrong" }
println(value.length)
Функция requireNotNull бросает IllegalArgumentException, поэтому ее удобно применять для проверки входных параметров функций. В то время как checkNotNull выбрасывает IllegalStateException. В остальном эти две функции идентичные.
Благодаря системе типов Котлин и контрактам, в простых случаях, как в примере выше, после вызова checkNotNull значение аргумента будет автоматически приведено из nullable к not-null типу.
Использование этих функций — хорошая альтернатива оператору !!.