Either — egy funkcionális típus, amely a két lehetséges változat egyikének értékét reprezentálja: bal (Left) a hibához és jobb (Right) a sikerhez. A kivételekkel ellentétben az Either explicité teszi a hibakezelést típus szinten, és nem igényel try-catch blokkokat. A Arrow, 2026 adatai szerint az Either széles körben használatos Kotlin projektekben olyan műveletek kompozíciójára, amelyek meghiúsulhatnak, mellékhatások nélkül.
Főbb pontok
Either — egy algebrai adattípus, amely a funkcionális programozásból származik, és pontosan egy értéket reprezentál a két lehetséges típus közül. A hibakezelés kontextusában az a konvenció: a bal típus (Left) tartalmazza a probléma leírását, a jobb (Right) pedig a sikeres eredményt.
Az Either koncepciója a Haskell nyelvből és az Either a b típuskategóriából ered, ahol a a bal érték típusa, b — a jobbé. A mobilfejlesztésben az Either a Kotlinhoz készült Arrow könyvtárnak és a Swift funkcionális megközelítéseinek köszönhetően vált népszerűvé.
Az Either legfőbb előnye a kivételekkel szemben — nincsenek rejtett végrehajtási útvonalak. Az Either-t visszaadó függvény explicit módon deklarálja az aláírásában, hogy hibával végződhet. A fordító ellenőrzi, hogy mindkét változat kezelve lett-e.
A kivételek dobásával ellentétben az Either megőrzi az adatfolyam átláthatóságát. Az Either-t visszaadó függvény meghívása nem igényel try-catch blokkot a hívó kód oldalán — elég a pattern-matching vagy a fold. Ez különösen fontos a reaktív megközelítésű architektúrákban, ahol minden adatforrás Either-t ad vissza, és a transzformációs lánc map és flatMap segítségével épül fel.
Az Either két altípusból áll: Left és Right. Egy Either példány minden pillanatban csak az egyik lehet. A tipikus aláírás Kotlinban Either<E, A>, ahol E a hiba típusa, A — a sikeres érték típusa.
Left a meghibásodás esetét reprezentálja. A kivételekkel ellentétben a Left nem szakítja meg a végrehajtási folyamatot — egyszerűen visszaad egy értéket, amelyet kezelni kell. A hiba típusa bármi lehet: String, Int, egyedi sealed class vagy domain modell.
Right tartalmazza a művelet helyes eredményét. A név a „helyességet” tükrözi — konvenció szerint a Right sikert jelent. A Right-on alkalmazzák a map és flatMap transzformációkat, ami lehetővé teszi számítási láncok építését az egyes lépések ellenőrzése nélkül.
flatMap — az Either kompozíciójának fő mechanizmusa. Ha az aktuális érték Right, a flatMap alkalmazza a megadott függvényt és visszaad egy új Either-t. Ha Left — a flatMap kihagyja a transzformációt és továbbadja a hibát. Ezt a viselkedést short-circuit evaluation-nak hívják.
A flatMap mellett az Either támogatja a mapLeft-et a hiba transzformálására, a fold-ot mindkét változat egy helyen történő kezelésére és a getOrElse-t az érték alapértelmezettel történő kinyerésére. Ezek a függvények lefedik az összes forgatókönyvet: az egyszerű kinyeréstől a bonyolult kompozícióig aszinkron hívásokkal Kotlin korutinokban vagy Combine-ben Swiftben.
fun parseInt(input: String): Either<String, Int> =
input.toIntOrNull()?.let { Right(it) }
?: Left("Nem sikerült konvertálni: $input")
fun divide(a: Int, b: Int): Either<String, Int> =
if (b == 0) Left("Osztás nullával")
else Right(a / b)
val result = parseInt("10")
.flatMap { divide(it, 2) }
A Kotlin ökoszisztémában az Either az Arrow könyvtárban van implementálva. A Kotlin szabványos könyvtára Result-ot kínál, de az Either nagyobb rugalmasságot nyújt: tetszőleges hibátípus, kompozíció flatMap segítségével és funkcionális minták támogatása.
Arrow — egy funkcionális könyvtár Kotlinhoz, amely hozzáadja az Either, Option, Validated és egyéb típusokat. Arrow.Either — sealed class két leszármazottal: ArrowCore.Left és ArrowCore.Right. A könyvtár kiterjesztéseket is biztosít a kényelmes munkához: .getOrElse(), .fold(), .mapLeft().
Tekintsünk egy valós forgatókönyvet — egy hálózati kérést egy Android alkalmazásban lehetséges hibákkal: nincs hálózat, szerverhiba, érvénytelen válasz. Az Either lehetővé teszi az összes változat egyetlen visszatérési típusba történő egyesítését.
sealed class NetworkError {
data class NoConnection(val message: String): NetworkError()
data class ServerError(val code: Int): NetworkError()
data class ParseError(val detail: String): NetworkError()
}
suspend fun fetchUser(id: String): Either<NetworkError, User> {
return try {
val response = api.getUser(id)
if (response.isSuccessful) {
Right(response.body()!!)
} else {
Left(NetworkError.ServerError(response.code()))
}
} catch (e: IOException) {
Left(NetworkError.NoConnection(e.message ?: ""))
}
}
A Swift ben az 5.0 verziótól kezdve megjelent a beépített Result típus, amely koncepcionálisan hasonlít az Either-ra, de korlátokkal rendelkezik: a hibának meg kell felelnie az Error protokollnak, a sikeres értéknek pedig egy típusnak. Az Either Swiftben enum segítségével implementálható két generikus paraméterrel.
Result<Success, Failure> — a Swift beépített típusa, ahol Failure: Error. Az Either nem korlátozza a hiba típusát, ami lehetővé teszi String, egyedi struktúrák vagy akár több hibátípus tárolását beágyazott enumok segítségével.
enum Either<E, A> {
case left(E)
case right(A)
func map<B>(_ transform: (A) -> B) -> Either<E, B> {
switch self {
case .left(let e): return .left(e)
case .right(let a): return .right(transform(a))
}
}
}
let result: Either<String, Int> = .right(42)
let mapped = result.map { $0 * 2 }
Either optimális azokhoz a forgatókönyvekhez, amelyek explicit és típusbiztos hibakezelést igényelnek kivételek nélkül. Tekintsük át a fő felhasználási eseteket a mobilfejlesztésben Kotlin és Swift nyelven.
Ne használja az Either-t egyszerű, mellékhatások nélküli műveletekhez — a szokásos visszatérési érték megbízhatóbb és olvashatóbb. Az Either szintén felesleges, ha a meghibásodás kivételes helyzet, nem pedig várható forgatókönyv.
Either hatékony a Kotlin korutinokkal való munkában is. Az Either-t visszaadó függvény meghívható egy korutinon belül hibakezeléssel fold vagy mapLeft segítségével anélkül, hogy blokkolná a szálat. Ez különösen hasznos az MVVM architektúrájú Android alkalmazásokban, ahol minden adattár Either-t ad vissza, és a ViewModel az eredményt UiState-té alakítja.
A fejlesztők, akik először találkoznak az Either-rel, gyakran követnek el hasonló hibákat. Tekintsük át a leggyakoribbakat és az elkerülésük módjait.
Gyakran Ismételt Kérdések
Optional az érték jelenlétét vagy hiányát reprezentálja (Some/None), de nem közli a hiány okát. Az Either két konkrét típust ad — bal oldalt a hiba és jobb oldalt a siker számára, ami lehetővé teszi a meghibásodás kontextusának átadását.
A Java-ban nincs beépített Either, de a Vavr és functionaljava könyvtárak biztosítanak implementációt. Az Android fejlesztésben a Vavr-ból származó Either népszerű alternatíva a funkcionális stílushoz lambdákkal.
Sealed class Kotlinban kényelmesebb, ha a változatok száma kettőnél több, vagy eltérő szerkezetűek. Bináris kimenet (hiba/siker) esetén az Either tömörebb és kész funkcionális kombinátorokat kínál.
Either immutable és alapértelmezetten szálbiztos. Kotlinban korutinokkal az Either kiválóan kombinálható: a flatMap a coroutine scope-on belül működik, a hibakezelés pedig nem igényel zárolást.
Nem. Either a várható meghibásodásokkal járó műveletekhez alkalmas (hálózat, érvényesítés, üzleti logika). Egyszerű getterekhez és mellékhatások nélküli számításokhoz a szokásos típus olvashatóbb és nem ad szükségtelen komplexitást.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is