#kotlin #builder #idioms
Вопрос:
Читал исходный код функции apply и нашел
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
и контракт имеет пустое тело, экспериментальное
@ContractsDsl
@ExperimentalContracts
@InlineOnly
@SinceKotlin("1.3")
@Suppress("UNUSED_PARAMETER")
public inline fun contract(builder: ContractBuilder.() -> Unit) { }
какова реальная цель контракта и останется ли он здесь в следующих версиях?
Ответ №1:
Какова реальная цель контракта
Реальная цель контрактов Kotlin состоит в том, чтобы помочь компилятору сделать некоторые предположения, которые не могут быть сделаны сами по себе. Иногда разработчик знает больше, чем компилятор, об использовании определенной функции, и этому конкретному использованию можно научить компилятор.
Я приведу пример с callsInPlace
тех пор, как вы упомянули об этом.
Представьте, что у вас есть следующая функция:
fun executeOnce(block: () -> Unit) {
block()
}
И призовите его таким образом:
fun caller() {
val value: String
executeOnce {
// It doesn't compile since the compiler doesn't know that the lambda
// will be executed once and the reassignment of a val is forbidden.
value = "dummy-string"
}
}
Здесь на помощь приходят контракты Котлина. Вы можете использовать callsInPlace
его для обучения компилятора тому, сколько раз будет вызываться эта лямбда.
@OptIn(ExperimentalContracts::class)
fun executeOnce(block: ()-> Unit) {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
}
@OptIn(ExperimentalContracts::class)
fun caller() {
val value: String
executeOnce {
// Compiles since the val will be assigned once.
value = "dummy-string"
}
}
это здесь, чтобы остаться в следующих версиях?
Кто знает. Они все еще являются экспериментальными после одного года, что нормально для основной функции. Вы не можете быть на 100% уверены, что они не будут экспериментальными, но, поскольку они полезны и находятся здесь с одного года, на мой взгляд, скорее всего, они выйдут из эксперимента.
Комментарии:
1. Спасибо, только что нашел эту полезную статью о контрактах blog.kotlin-academy.com/…