val și var în Kotlin

Bazele programului Kotlin 1.0

val declară o variabilă care nu mai poate fi schimbată după atribuire; var declară una care poate primi altă valoare.

Sintaxă
val nume = valoare          // nu poate fi reatribuită
var nume = valoare          // poate primi altă valoare
val nume: Tip = valoare     // cu tip explicit

Ce face val și var

val (de la „value”) declară o variabilă cu o singură atribuire: după ce a primit o valoare, nu mai poate primi alta. var (de la „variable”) declară o variabilă obișnuită, care poate fi schimbată oricând. Regula din Kotlin: folosește val peste tot și treci la var doar când chiar ai nevoie să modifici valoarea.

Tipul se deduce din valoare: val oras = "Iași" este String, var puncte = 0 este Int. Îl poți scrie și explicit, după două puncte: val pret: Double = 10.0. Tipul nu se mai schimbă: unei variabile Int nu îi poți atribui un text.

val înseamnă că variabila nu poate indica alt obiect, nu că obiectul este imutabil. O val lista = mutableListOf(1) nu poate primi altă listă, dar lista însăși poate primi elemente noi cu add.

Exemple

Exemplul 1: val pentru valori fixe, var pentru contor

numeClient și pretCafea nu se schimbă, deci sunt val. total crește la fiecare comandă, deci este var.

fun main() {
    val numeClient = "Ana"
    val pretCafea = 9.5
    var total = 0.0

    total += pretCafea
    total += pretCafea
    total += 12.0   // o prăjitură

    println("$numeClient are de plată $total lei")
}

Rezultat

Ana are de plată 31.0 lei

Exemplul 2: val cu o listă care se modifică

Variabila cos indică mereu aceeași listă, dar conținutul listei se schimbă. O atribuire cos = mutableListOf() nu ar compila.

fun main() {
    val cos = mutableListOf("pâine", "lapte")
    cos.add("ouă")
    cos.remove("lapte")
    println("În coș: $cos")

    var mesaj: String = "coș gol"
    if (cos.isNotEmpty()) {
        mesaj = "${cos.size} produse"
    }
    println(mesaj)
}

Rezultat

În coș: [pâine, ouă]
2 produse

Exemplul 3: val atribuită o singură dată, mai târziu

O val locală poate fi declarată fără valoare și primi una mai târziu, o singură dată pe fiecare ramură. Compilatorul verifică asta.

fun main() {
    val temperaturi = listOf(18, 24, 31)
    for (t in temperaturi) {
        val sfat: String
        if (t > 30) {
            sfat = "stai la umbră"
        } else if (t > 20) {
            sfat = "vreme de plimbare"
        } else {
            sfat = "ia o geacă"
        }
        println("$t °C: $sfat")
    }
}

Rezultat

18 °C: ia o geacă
24 °C: vreme de plimbare
31 °C: stai la umbră

Greșeli frecvente

  • Folosirea lui var din obișnuință: dacă variabila nu se schimbă, scrie val. Codul devine mai ușor de urmărit.
  • val x = 5 urmat de x = 6: eroarea 'val' cannot be reassigned.
  • A crede că val face obiectul imutabil: pentru o listă care nu se poate modifica folosește listOf, nu mutableListOf.

Comenzi înrudite

  • const val: const val declară o constantă cunoscută la compilare (număr, text, Boolean), înlocuită direct în cod.
  • lateinit: lateinit permite unei proprietăți var ne-nullable să primească valoare mai târziu, după crearea obiectului.
  • get și set (getteri și setteri): get și set definesc ce se întâmplă când o proprietate este citită sau modificată; field este valoarea păstrată în spate.
  • String templates ($nume, ${expresie}): Pun valoarea unei variabile sau a unei expresii direct în text, cu $nume sau ${expresie}.