> Что такое contracts в Kotlin и когда их используют? (Kotlin, Android)
Уровень: junior · Роль: mobile · Категория: Технические вопросы
Компании: Альфа-банк
Стек: Kotlin, Android
> Пример ответа
Короткий ответ
Contracts в Kotlin - это механизм, который сообщает компилятору дополнительную информацию о поведении функций, например, что функция возвращает true только при определённых условиях. Их используют для улучшения smart cast и анализа кода. На практике чаще всего встречаются в стандартной библиотеке, например, в check(), require() или let(). Для junior-разработчика важно понимать, что contracts позволяют компилятору делать выводы, которые он не может сделать самостоятельно.
Подробное объяснение
Contracts - это экспериментальная (на момент Kotlin 1.x) фича, которая позволяет разработчику объявлять контракты для функций. Контракт описывает, как функция влияет на поток управления или на состояние аргументов. Компилятор использует эту информацию для:
- улучшения smart cast (например, после проверки
isNotEmpty()компилятор знает, что строка не пустая); - анализа инициализации переменных (например,
checkNotNull()); - улучшения работы с nullable-типами.
Основные виды контрактов:
returns(true)/returns(false)- функция возвращает конкретное значение;returnsNotNull()- функция не возвращаетnull;callsInPlace(block, InvocationKind.EXACTLY_ONCE)- лямбда вызывается ровно один раз, что позволяет компилятору разрешить инициализациюvalвнутри лямбды.
Contracts объявляются с помощью аннотации @ExperimentalContracts и функции contract { } внутри тела функции. Важно: contracts не влияют на рантайм, они работают только на этапе компиляции.
На практике
В повседневной Android-разработке вы редко будете писать свои contracts. Чаще вы будете пользоваться функциями, которые их уже используют. Например:
check()иrequire()- для валидации состояния;checkNotNull()- для проверки на null;let(),also(),apply()- для работы с nullable-объектами;isNullOrEmpty()иisNotNullOrEmpty()- для строк и коллекций.
Понимание contracts помогает читать код и предсказывать поведение компилятора. Например, если вы видите checkNotNull(x), то после этой строки компилятор считает x непустым, и вам не нужен !!.
Пример кода
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @OptIn(ExperimentalContracts::class) fun String?.isNotNullAndNotEmpty(): Boolean { contract { returns(true) implies (this@isNotNullAndNotEmpty != null) } return this != null && this.isNotEmpty() } fun process(input: String?) { if (input.isNotNullAndNotEmpty()) { // здесь компилятор знает, что input не null и не пустая println(input.length) // smart cast работает без !! } }
Как отвечать на собеседовании
Начните с простого определения: contracts - это подсказки компилятору. Затем приведите пример из стандартной библиотеки, например, checkNotNull(). Объясните, что contracts не влияют на производительность и не выполняются в рантайме. Если спросят про callsInPlace, упомяните, что это позволяет инициализировать val внутри лямбды, как в lazy {}. Не углубляйтесь в детали реализации, если не просят.
Что проверяет интервьюер
Интервьюер проверяет:
- понимание базовой идеи - contracts как информация для компилятора;
- знание типичных функций с contracts из стандартной библиотеки;
- понимание разницы между compile-time и runtime поведением;
- способность объяснить, зачем это нужно на практике.
Для junior-уровня достаточно уверенного ответа на уровне "это помогает компилятору делать smart cast" и пример с checkNotNull().
Типичные ошибки
- Путать contracts с аннотациями вроде
@Nullableили@NonNull- это разные механизмы. - Говорить, что contracts "ускоряют код" - они не влияют на рантайм.
- Пытаться объяснить сложные случаи с
callsInPlace, если не уверены в деталях. - Использовать
!!послеcheckNotNull()- это показывает непонимание, что contracts уже сделали работу. - Забывать, что contracts - экспериментальная фича, и для их использования нужна opt-in аннотация.
> Похожие задачи по mobile
В каких случаях использовать модификаторы in и out в дженериках Kotlin
Можно ли изменить значение val в дата классе через рефлексию
Как проверить тип параметра в обобщённом методе Kotlin
Что такое Coroutine Builders в Kotlin
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью