Either: lényeg, alkalmazás és működési elv

Szerző: IT Sectr Megjelenés: 2026-05-26 Olvasási idő: 8 perc

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 két egymást kizáró változat reprezentálására: Left (hiba) és Right (siker).
  • Left hagyományosan a hibára vonatkozó információt tartalmazza, Right — a helyes értéket.
  • Explicit típusosztás — Az Either mindkét változat kezelését kötelezővé teszi fordítási időben, kiküszöbölve a váratlan meghibásodásokat.
  • Kompozíció — Az Either támogatja a map, flatMap és fold függvényeket transzformációs láncokhoz beágyazott ellenőrzések nélkül.
  • Különbség a Result-tól — Az Either tetszőleges hibátípust tárolhat, nem csak Error vagy Throwable típust.

Mi az Either?

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.

Hogyan működik az Either: a Left és Right szerkezete

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 típus: hiba konténer

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 típus: siker konténer

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.

Az Either kompozíciója flatMap segítségével

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.

kotlin
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) }

Either Kotlinban: gyakorlati alkalmazás

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 könyvtár és Either

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().

Példa: Either hálózati kéréssel

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.

kotlin
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 ?: ""))
    }
}

Either Swiftben: különbség a standard Result-tól

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.

Standard Result kontra Either

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.

swift
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 }

Mikor használjuk az Either-t mobilalkalmazásokban

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.

  • Hálózati kérések — minden kérés visszaadhat kapcsolódási, szerver- vagy feldolgozási hibát. Az Either összegyűjti az összes változatot egy típusba.
  • Űrlap-ellenőrzés — Az Either egyedi hibátípussal kényelmesen reprezentálja a beviteli mezők ellenőrzésének eredményét: érvénytelen e-mail vagy jelszó.
  • Adattár — Az Either lehetővé teszi a különböző forrásokból (gyorsítótár, adatbázis, hálózat) származó eredmények egyesítését egységes hibátípussal.
  • Parancsértelmező — ha az alkalmazás felhasználói bemenetet vagy parancsokat elemez, az Either típusbiztos módot biztosít a hiba jelentésére.

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.

Gyakori hibák az Either-rel való munkában

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.

  • A Left figyelmen kívül hagyása — a .getOrElse() hívása alapértelmezett értékkel a hiba okának elemzése nélkül értelmetlenné teszi az Either használatát. Kezelje a hibát explicit módon.
  • Globális hibátípus — a String vagy Exception használata közös típusként az összes Either számára a projektben csökkenti a típusbiztonságot. Hozzon létre domain sealed class-okat.
  • Beágyazott Either-ök — ismételt Either a Right-on belül (Either<E, Either<E, A>>) nehezíti az olvasást. Használjon flatMap-et a kilapításhoz.
  • Keverés kivételekkel — a függvény Either-t ad vissza, de belül kivételt dob. Ez ellentmond az explicit hibakezelés elvének.

Gyakran Ismételt Kérdések

Miben különbözik az Either az Optional-tól?

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.

Használható az Either Java-ban?

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.

Mikor érdemes sealed class-t használni Either helyett?

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.

Támogatja az Either a többszálúságot?

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.

Érdemes az Either-t használni a projekt összes függvényéhez?

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

  • Either — funkcionális típus két változat reprezentálására: Left (hiba) és Right (siker), amely explicité teszi a meghibásodás kezelését típus szinten.
  • Left bármilyen hibátípust tartalmazhat — String-től domain sealed class-ig, ellentétben a standard Result-tal.
  • flatMap biztosítja az Either kompozícióját beágyazott ellenőrzések nélkül: a hiba automatikusan propagálódik a teljes láncon keresztül.
  • Arrow — a fő Either könyvtár Kotlinhoz beépített korutin- és kiterjesztés-támogatással.
  • Swift a beépített Result-ot használja, de az Either enum segítségével implementálható két generikus paraméterrel a teljes rugalmasság érdekében.
  • Alkalmazza az Either-t hálózati kérésekhez, űrlap-ellenőrzéshez és adattárakhoz — várható hibákkal járó forgatókönyvekhez.
  • Kerülje a globális hibátípust, a Left figyelmen kívül hagyását és a beágyazott Either-öket — ezek csökkentik a típusbiztonság előnyeit.

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.

Projekt megbeszélése

Olvassa el is