Pattern Matching Avansat și Enumerări cu Valori Asociate în Swift în Swift (iOS & macOS)

Ghid complet pentru enumerările Swift și pattern matching avansat: sum types, valori asociate (associated values), enumerări recursive cu indirect, operatorul ~= și expresii de filtrare cu if case, guard case și clauze where.

Sintaxă Swift
if case .success(let data) = res where data.isValid { ... } | indirect enum Node

În multe limbaje C-like, o enumerare este doar o listă de numere întregi etichetate. În Swift, enumerările sunt Algebraic Data Types (Sum Types) de nivel înalt: fiecare caz poate stoca valori asociate de tipuri arbitrare (Associated Values), pot deține metode, proprietăți calculate și conformări la protocoale, reprezentând una dintre cele mai puternice facilități ale limbajului.

Enumerări cu Valori Asociate și Pattern Matching Avansat
// 1. Definirea unei enumerări expresive pentru starea unei conexiuni:
enum StareRetea {
    case deconectat
    case conectare(incercare: Int)
    case conectat(adresaIP: String, latentaMs: Double)
    case eroare(cod: Int, mesaj: String)
}

let conexiune = StareRetea.conectat(adresaIP: "192.168.1.10", latentaMs: 14.5)

// 2. Evaluare exhaustivă cu clauze 'where':
switch conexiune {
case .deconectat:
    print("Nu există conexiune la rețea.")
case .conectare(let incercare) where incercare > 3:
    print("Conectarea întârzie (încercarea \(incercare))...")
case .conectare:
    print("Negociere handshake în curs...")
case .conectat(let ip, let latenta) where latenta < 20.0:
    print("Conectat la \(ip) cu latență ultra-rapidă: \(latenta)ms!")
case .conectat(let ip, _):
    print("Conectat la \(ip).")
case .eroare(404, _):
    print("Serverul nu a fost găsit.")
case .eroare(let cod, let mesaj):
    print("Eroare de sistem [\(cod)]: \(mesaj)")
}

// 3. Sintaxă condensată cu 'if case' și 'guard case':
if case .conectat(let ip, _) = conexiune {
    print("IP-ul activ este: \(ip)")
}

Enumerări Recursive cu cuvântul cheie indirect

Dacă un caz de enumerare conține o valoare asociată de același tip cu enumerarea însăși (de exemplu o structură arborescentă sau o listă înlănțuită), Swift cere marcarea cu indirect pentru a aloca un pointer pe heap și a evita o dimensiune infinită pe stivă:

indirect enum ExpresieAritmetica {
    case numar(Int)
    case adunare(ExpresieAritmetica, ExpresieAritmetica)
    case inmultire(ExpresieAritmetica, ExpresieAritmetica)
}

func evalueaza(_ expr: ExpresieAritmetica) -> Int {
    switch expr {
    case .numar(let val):
        return val
    case .adunare(let stanga, let dreapta):
        return evalueaza(stanga) + evalueaza(dreapta)
    case .inmultire(let stanga, let dreapta):
        return evalueaza(stanga) * evalueaza(dreapta)
    }
}

// (5 + 4) * 2 = 18
let calcul = ExpresieAritmetica.inmultire(
    .adunare(.numar(5), .numar(4)),
    .numar(2)
)
print("Rezultat calcul: \(evalueaza(calcul))")