Contracte de Funcție și Smart Casts Avansate în Kotlin 2.0 (K2 Compiler) în Kotlin

Funcții și lambda Kotlin 2.0

Ghid complet pentru Kotlin Contracts: declararea promisiunilor către compilatorul K2, deblocarea Smart Casts automate după funcții de validare și contractul callsInPlace pentru lambda-uri executate exact o singură dată.

Sintaxă
contract { returns() implies (value != null) } | callsInPlace(block, EXACTLY_ONCE)

Chiar dacă Kotlin posedă cel mai inteligent sistem de Smart Casts din industrie (transformă automat o referință verificată cu if (x is String) în tipul concret), compilatorul nu poate deduce în mod nativ ce se întâmplă în interiorul unei funcții externe de validare:

fun verificaText(text: String?) {
    if (text.isNullOrBlank()) throw IllegalArgumentException()
}

fun main() {
    val s: String? = "Kotlin"
    verificaText(s)
    // Fără contracte, compilatorul NU știe că 's' nu mai poate fi null aici!
    // println(s.length) // EROARE fără contracte!
}

Pentru a rezolva această deconectare, Kotlin introduce Contractele de Funcție (Kotlin Contracts) prin blocul contract { ... }, permițând unei funcții să comunice explicit compilatorului K2 garanțiile pe care le oferă la ieșire.

Definirea unui Contract de Verificare de Nenulabilitate
import kotlin.contracts.*

// Funcție utilitară de validare cu contract explicit:
@OptIn(ExperimentalContracts::class)
fun valideazaNenul(valoare: Any?) {
    contract {
        // Promisiune către compilatorul K2: 
        // Dacă această funcție se returnează normal (fără a arunca excepție),
        // atunci 'valoare' este garantat diferită de NULL!
        returns() implies (valoare != null)
    }

    if (valoare == null) {
        throw IllegalArgumentException("Eroare critică: valoarea nu poate fi nulă!")
    }
}

fun testSmartCast(input: String?) {
    valideazaNenul(input)
    
    // Datorită contractului, K2 activează automat Smart Cast:
    println("Lungimea este: ${input.length}") // 100% sigur, 'input' este tratat ca String nenulabil!
}

Contractul callsInPlace pentru Inițializarea Variabilelor val

Un alt contract esențial informează compilatorul despre frecvența cu care o funcție lambda este executată:

@OptIn(ExperimentalContracts::class)
inline fun  executaRapid(block: () -> R): R {
    contract {
        // Garantează că 'block' este apelat EXACT o singură dată pe loc:
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

fun calcul() {
    val rezultat: Int // Variabilă imutabilă neinițializată
    executaRapid {
        rezultat = 42 // Permis! Compilatorul știe că block-ul rulează EXACT o dată!
    }
    println(rezultat)
}