Either<L, R>: gestione tipizzata degli errori senza eccezioni
Utilizzi Either per rappresentare successo e fallimento senza generare eccezioni.
Either<L, R>: gestione tipizzata degli errori senza eccezioni è una lezione Kotlin Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Kotlin Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Kotlin Academy include 4 lezioni in totale.
Il problema delle eccezioni per la logica di business
Le eccezioni sono progettate per gli errori imprevisti (null pointer, errore di I/O). Usarle per segnalare errori di business previsti (errore di validazione, "non trovato") rende invisibile il flusso di controllo, obbliga a inserire try/catch in ogni punto di chiamata e nasconde gli errori nelle signature delle funzioni.
Che cos'è Either<L, R>?
Either è un sum type con due casi: Left(value: L) contiene convenzionalmente l'errore, mentre Right(value: R) contiene convenzionalmente il valore restituito in caso di successo. Una funzione che restituisce Either rende esplicita nella propria signature la possibilità di un errore.
Either di Arrow
Aggiunga Arrow al progetto per ottenere Either e il suo intero ecosistema di operatori:
// build.gradle.kts
implementation("io.arrow-kt:arrow-core:1.2.4")
// Usage
import arrow.core.Either
import arrow.core.left
import arrow.core.rightRestituire Either da una funzione
Restituisca value.right() in caso di successo e error.left() in caso di errore. Il chiamante deve gestire entrambi i rami:
sealed class UserError { object NotFound : UserError(); data class InvalidEmail(val msg: String) : UserError() }
fun findUser(id: Long): Either<UserError, User> =
if (id <= 0) UserError.NotFound.left()
else User(id, "Alice").right()Consumare Either con fold
Utilizzi fold(ifLeft, ifRight) per gestire entrambi i casi in un'unica espressione:
val result = findUser(1L)
val message = result.fold(
ifLeft = { error -> "Error: $error" },
ifRight = { user -> "Found: ${user.name}" }
)
println(message)Trasformare il valore Right con map
map { } trasforma il valore Right senza modificare un Left. In questo modo Either è un functor: è possibile concatenare le trasformazioni in modo sicuro:
val nameResult: Either<UserError, String> = findUser(1L).map { it.name }Concatenamento con flatMap
flatMap { } concatena calcoli che restituiscono a loro volta Either. Se un passaggio restituisce Left, la catena si interrompe e l'errore viene propagato senza eseguire i passaggi successivi:
fun validateEmail(email: String): Either<UserError, String> =
if (email.contains("@")) email.right()
else UserError.InvalidEmail("bad format").left()
fun createUser(email: String): Either<UserError, User> =
validateEmail(email).flatMap { validEmail ->
User(1L, validEmail).right()
}Either.catch per racchiudere le eccezioni
Either.catch { } esegue un blocco e racchiude qualsiasi eccezione in un Left. Lo utilizzi al confine tra il codice legacy che genera eccezioni e il dominio basato su Either:
val result: Either<Throwable, User> = Either.catch {
userRepository.findOrThrow(id)
}Recupero con getOrElse e orElse
getOrElse { default } estrae il valore Right oppure restituisce un valore predefinito. orElse { alternativeEither } sostituisce un Left con un altro calcolo:
val user: User = findUser(0L).getOrElse { User(-1L, "Guest") }
val user2: Either<UserError, User> = findUser(0L).orElse { User(99L, "Default").right() }Pattern matching con when
Utilizzi when su una classe sealed simile a Either oppure direttamente su Either con is Either.Left / Either.Right per gestire esaustivamente tutti i casi:
when (val r = findUser(1L)) {
is Either.Left -> println("Error: ${r.value}")
is Either.Right -> println("User: ${r.value.name}")
}Either nei service layer
Restituisca Either dalle funzioni del repository e del service. Lo trasformi in risposte HTTP a livello della route Ktor, mantenendo la logica di business indipendente dagli aspetti specifici del framework:
get("/users/{id}") {
val id = call.parameters["id"]?.toLongOrNull() ?: return@get call.respond(HttpStatusCode.BadRequest)
userService.findById(id).fold(
ifLeft = { call.respond(HttpStatusCode.NotFound) },
ifRight = { call.respond(it) }
)
}Verifica rapida
Che cosa fa flatMap { } su un valore Either.Left?
Riepilogo: Either<L, R>
Punti chiave:
Eitherrende esplicito il percorso di errore nella signature della funzioneRight= successo;Left= errore (per convenzione)map { }— trasforma il valore restituito in caso di successo;flatMap { }— concatena calcoli che possono fallirefold(ifLeft, ifRight)— consuma entrambi i casi in un'unica espressioneEither.catch { }— racchiude il codice che genera eccezioni ai confini del sistema
Domande Frequenti
La lezione «Either<L, R>: gestione tipizzata degli errori senza eccezioni» è gratuita?
Sì — il testo completo di «Either<L, R>: gestione tipizzata degli errori senza eccezioni» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Kotlin Academy, passa a CoddyKit PRO. Il corso Kotlin Academy include 4 lezioni in totale.
Cosa imparerò in «Either<L, R>: gestione tipizzata degli errori senza eccezioni»?
Utilizzi Either per rappresentare successo e fallimento senza generare eccezioni. Eserciti Kotlin Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Kotlin Academy?
Non è richiesta alcuna esperienza precedente. Kotlin Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Either<L, R>: gestione tipizzata degli errori senza eccezioni»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Kotlin Academy?
Sì. Ogni lezione Kotlin Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Either : gestione tipizzata degli errori senza eccezioni
- DSL Raise di Arrow: composizione degli errori tipizzati
- Option e nullable: quando utilizzare ciascuno
- Modellazione funzionale del dominio con i tipi fondamentali di Arrow