require în Kotlin

Verifică argumentele unei funcții și aruncă IllegalArgumentException dacă nu sunt bune; requireNotNull cere o valoare diferită de null.

Sintaxă
fun require(value: Boolean)
inline fun require(value: Boolean, lazyMessage: () -> Any)
inline fun <T : Any> requireNotNull(value: T?, lazyMessage: () -> Any): T

Ce face require

require(conditie) { "mesaj" } se pune la începutul unei funcții pentru a verifica argumentele primite. Dacă condiția este falsă, aruncă IllegalArgumentException cu mesajul din bloc. Blocul cu mesajul rulează doar la eroare, deci nu costă nimic când totul e în regulă.

requireNotNull(valoare) { "mesaj" } verifică dacă valoarea nu este null și o returnează cu tipul fără ?. După apel, compilatorul știe că valoarea există (smart cast).

Regula: require pentru greșeli ale celui care apelează funcția (argumente), check pentru starea obiectului, error pentru situații imposibile.

Parametri

Parametru Descriere
value Condiția care trebuie să fie adevărată (la require) sau valoarea care nu trebuie să fie null (la requireNotNull).
lazyMessage: () -> Any Bloc care produce mesajul excepției; rulează doar dacă verificarea eșuează. Fără el, mesajul este „Failed requirement.”.

Ce returnează

require: nimic. requireNotNull: valoarea, cu tip non-null. Ambele aruncă IllegalArgumentException la eșec.

Exemple

Exemplul 1: Verificarea argumentelor unei funcții

Al doilea și al treilea apel nu trec de require; excepția este prinsă și i se afișează mesajul.

fun retrage(sold: Double, suma: Double): Double {
    require(suma > 0) { "Suma trebuie să fie pozitivă, nu $suma" }
    require(suma <= sold) { "Fonduri insuficiente: sold $sold lei, ceri $suma lei" }
    return sold - suma
}

fun main() {
    println("Sold nou: ${retrage(500.0, 120.0)} lei")
    for (suma in listOf(-10.0, 900.0)) {
        try {
            retrage(500.0, suma)
        } catch (e: IllegalArgumentException) {
            println("Eroare: ${e.message}")
        }
    }
}

Rezultat

Sold nou: 380.0 lei
Eroare: Suma trebuie să fie pozitivă, nu -10.0
Eroare: Fonduri insuficiente: sold 500.0 lei, ceri 900.0 lei

Exemplul 2: requireNotNull și mesajul implicit

După requireNotNull, oras are tipul String, deci length se folosește fără ?.. Fără bloc de mesaj, require dă „Failed requirement.”.

fun lungimeOras(date: Map<String, String>): Int {
    val oras = requireNotNull(date["oras"]) { "Lipsește câmpul „oras”" }
    return oras.length
}

fun main() {
    println(lungimeOras(mapOf("oras" to "Constanța")))
    try {
        lungimeOras(mapOf("nume" to "Ana"))
    } catch (e: IllegalArgumentException) {
        println(e.message)
    }
    try {
        val note = listOf(4, 3)
        require(note.all { it >= 5 })
    } catch (e: IllegalArgumentException) {
        println(e.message)
    }
}

Rezultat

9
Lipsește câmpul „oras”
Failed requirement.

Greșeli frecvente

  • Folosești require pentru starea obiectului (de exemplu „conexiunea e deschisă”). Excepția corectă acolo este IllegalStateException, dată de check.
  • Construiești mesajul ca text normal: require(x > 0, "mesaj") nu compilează. Mesajul se dă într-un bloc: require(x > 0) { "mesaj" }.

Comenzi înrudite

  • check: Verifică starea programului și aruncă IllegalStateException dacă nu este cea așteptată; checkNotNull cere o valoare diferită de null.
  • error: error aruncă imediat IllegalStateException cu un mesaj; TODO marchează cod încă nescris și aruncă NotImplementedError.
  • runCatching: Rulează un bloc și prinde orice excepție într-un Result; valoarea se scoate cu getOrNull, getOrElse sau getOrThrow.