in și !in în Kotlin

in verifică dacă o valoare aparține unui interval, unei colecții sau unui text; tot in se folosește în for.

Sintaxă
for (x in colectie) { ... }
if (x in 1..10) { ... }
if (x !in lista) { ... }
when (x) { in 1..5 -> ... }

Ce face in și !in

in are două roluri. În for (x in colectie) înseamnă „pentru fiecare element din”. Într-o expresie, x in colectie întoarce true dacă valoarea se găsește acolo; x !in colectie este negația. Funcționează cu intervale (nota in 1..10), liste, mulțimi, chei de map și texte ("ana" in "banana").

a in b este scrierea scurtă pentru b.contains(a). Orice clasă care are operator fun contains poate fi folosită cu in. La un interval verificarea este instantanee (două comparații); la o listă, elementele sunt verificate unul câte unul.

Cuvântul in apare și la generics, ca modificator de varianță (Comparator<in T>), cu alt sens: tipul doar intră în funcții. Vezi pagina despre out și in.

Ce returnează

Într-o expresie: Boolean.

Exemple

Exemplul 1: Verificări rapide cu in

Aceeași scriere merge pentru interval, listă, text și cheile unui map.

fun main() {
    val nota = 11
    println("nota validă: ${nota in 1..10}")

    val judeteMoldova = listOf("IS", "SV", "BT", "NT", "BC", "VS", "VN", "GL")
    println("IS e în Moldova: ${"IS" in judeteMoldova}")
    println("CJ nu e în Moldova: ${"CJ" !in judeteMoldova}")

    println("„nas” apare în „Ionașcu”? ${"nas" in "Ionașcu"}")

    val preturi = mapOf("pâine" to 5.0, "lapte" to 7.5)
    println("avem preț pentru ouă? ${"ouă" in preturi}")
}

Rezultat

nota validă: false
IS e în Moldova: true
CJ nu e în Moldova: true
„nas” apare în „Ionașcu”? false
avem preț pentru ouă? false

Exemplul 2: in în when și pentru caractere

Intervalele de caractere ('a'..'z') se verifică la fel ca cele de numere.

fun tip(c: Char) = when (c) {
    in 'a'..'z', in 'A'..'Z' -> "literă"
    in '0'..'9' -> "cifră"
    in "ăâîșțĂÂÎȘȚ" -> "literă românească"
    else -> "alt simbol"
}

fun main() {
    for (c in "Ș1a?") {
        println("'$c' este ${tip(c)}")
    }
}

Rezultat

'Ș' este literă românească
'1' este cifră
'a' este literă
'?' este alt simbol

Exemplul 3: in pentru clasa ta (operator contains)

Clasa Program definește operator fun contains, așa că ora in program devine apelul program.contains(ora).

class Program(private val deschidere: Int, private val inchidere: Int) {
    operator fun contains(ora: Int): Boolean = ora >= deschidere && ora < inchidere
}

fun main() {
    val farmacie = Program(8, 20)
    for (ora in listOf(7, 8, 19, 20)) {
        val mesaj = if (ora in farmacie) "deschis" else "închis"
        println("ora $ora: $mesaj")
    }
}

Rezultat

ora 7: închis
ora 8: deschis
ora 19: deschis
ora 20: închis

Greșeli frecvente

  • x in 1..10 când vrei să excluzi 10: .. include capătul. Folosește 1..<10 sau 1 until 10.
  • in pe o listă foarte mare, în buclă: fiecare verificare parcurge lista. Pentru multe verificări transformă lista într-un Set (toSet()).
  • in pe un map caută în chei, nu în valori. Pentru valori: map.containsValue(v) sau v in map.values.

Comenzi înrudite

  • for: Parcurge pe rând elementele unei colecții, ale unui interval sau ale oricărui obiect care are iterator().
  • Range-uri (.., ..<, until, downTo, step): Intervale de numere sau caractere: .. include capătul, ..< și until îl exclud, downTo numără invers, step sare.
  • when: Alege o ramură după valoarea unei expresii sau după prima condiție adevărată; înlocuiește switch din alte limbaje.
  • operator: operator marchează o funcție cu nume special (plus, get, contains, compareTo…) ca să poată fi folosită prin +, [], in sau <.
  • out și in (varianță): out și in spun cum se moștenesc tipurile generice: out T doar produce valori (covariant), in T doar le consumă (contravariant).