Это небольшая статья, рассказывает о том, как сделать код приложения чище, используя Contract API языка Kotlin.
РЕКОМЕНДУЕМ:
- Современный подход к разработке с использованием Kotlin
- Как сделать код на Kotlin более понятным
- Хорошие и плохие приемы программирования на Kotlin
Представим, что у нас есть следующая функция:
1 |
val Any?.isNull: Boolean get() = this == null |
Она позволяет нам писать такой код:
1 |
if (name.isNull) { ... } |
Вместо такого:
if (name == null) { ... }
Однако есть небольшая проблема. Следующий код вызовет ошибку компилятора и предупреждение среды разработки о том, что в третьей строке происходит обращение к nullable-переменной:
1 2 3 |
val name: String? = null if (name.isNull) return println("name is ${name.length} characters long") |
Так происходит потому, что анализатор кода в среде разработки и компиляторе не в состоянии определить, что в третьей строке name гарантированно не может быть null.
К счастью, мы можем это исправить, используя контракты:
1 2 3 4 5 6 7 8 9 10 11 |
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract@OptIn(ExperimentalContracts::class) import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract@OptIn(ExperimentalContracts::class) fun Any?.isNull(): Boolean { contract { returns(false) implies (this@isNull != null) } return this == null } |
От предыдущей реализации данная функция‑расширение отличается появившимся блоком contract. Он как раз и дает анализатору кода подсказку, что если возвращаемое этой функцией значение равно false, то текущий объект не равен null.
Это только один пример использования контрактов. В библиотеке Kotlin есть множество других примеров, включая функцию requireNotNull. Использовать ее можно так:
1 2 3 4 5 |
fun main() { val name: String? = null requireNotNull(name) println("name is ${name.length} characters long") } |
А код функции выглядит так:
1 2 3 4 5 6 |
public inline fun requireNotNull(value: T?): T { contract { returns() implies (value != null) } return requireNotNull(value) { "Required value was null." } } |
Это выжимка статьи Using Kotlin’s Contract APIs for Smarter Helper Functions