Result Type: bu nima, Result konteyner tipi va mobil ishlanmada qanday ishlaydi

Muallif: IT Sectr Nashr etilgan: 2026-05-26 O'qish vaqti: 9 daq

Result Type — bu muvaffaqiyat (Success) yoki xato (Failure) bilan tugashi mumkin bo'lgan operatsiya natijasini ifodalovchi konteyner tipidir. Istisnolardan farqli o'laroq, Result xatoni oddiy qiymat sifatida uzatadi, stackni ochmasdan, bu kutilgan xatolarni boshqarishni xavfsizroq va kompozitsiyali qiladi. Apple Swift Documentation (2026) ga ko'ra, Swift da Result<Success, Failure> dastur bajarilishini to'xtatmasdan map va flatMap orqali avtomatik xato boshqaruvi bilan operatsiyalar zanjirlarini birlashtirish imkonini beradi.

Asosiy fikrlar

  • Result Type — ikki holatli generic konteyner: Success (ma'lumot) va Failure (xato), stack ochilmasdan
  • Swift da Result<Success, Failure> — map, flatMap, mapError va get metodlari bilan o'rnatilgan tip
  • Kotlin da Result<T> muvaffaqiyat yoki Throwable ni ifodalaydi, getOrNull, getOrDefault, fold funksiyalari bilan
  • Dart da standart Result<T> Dart 3.0 dan boshlab mavjud, shuningdek fpdart paketidan Either
  • Kompozitsiya map va flatMap orqali Result qaytaradigan bir nechta operatsiyalarni ichma-ich tekshirishlarsiz birlashtirish imkonini beradi

Result Type nima?

Result Type — bu ham muvaffaqiyatli, ham xato bilan tugashi mumkin bo'lgan operatsiya bajarilishi natijasini inkapsulatsiya qiluvchi generic tipdir. Istisnolardan farqli o'laroq, bu yerda xato normal bajarilish oqimini to'xtatadi va catch topish uchun stack ochilishini talab qiladi, Result xatoni oddiy qiymat sifatida uzatadi — chaqiruvchi tomon har doim obyektni oladi va u bilan qanday munosabatda bo'lishni o'zi hal qiladi. Bu, ayniqsa, kutilgan xatolar uchun foydalidir: noto'g'ri kiritish, biznes qoidalari, server rad etishi, bu yerda istisno juda og'ir mexanizm bo'lar edi.

Result kontseptsiyasi funksional dasturlashdan kelib chiqqan, bu yerda o'xshash turlar Either (yoki Left/Right) deb ataladi. Swift da Result Swift 5.0 da standart turga aylandi, Kotlin da Result<T> standart kutubxonada paydo bo'ldi, Dart 3.0 da — o'rnatilgan Result<T>. Har bir implementatsiya konteyner bilan ishlash uchun metodlarni taqdim etadi: map (muvaffaqiyatli qiymatni transformatsiya qilish), flatMap (Result funksiyalari zanjiri), mapError (xatoni transformatsiya qilish), fold (har ikki holni boshqarish). Result Type — mobil ishlanmada funksional xato boshqaruvining tamal toshi, kutilgan stsenariylar uchun try-catch alternativi.

Result ning asosiy afzalligi — kompozitsiyalilik. Har biri xato qaytarishi mumkin bo'lgan bir nechta operatsiyalarni ichma-ich try-catch larsiz bitta zanjirda birlashtira olasiz. Zanjirdagi har qanday operatsiya Failure bilan tugasa, butun zanjir to'xtatiladi va Failure qaytariladi — bitta if sharti yoki catch blokisiz. Bu kodni chiziqli va o'qishli qiladi, ayniqsa ko'p sonli ketma-ket API so'rovlari yoki biznes qoidalarini tekshirish stsenariylarida.

Swift da Result

Swift da Result<Success, Failure> — ikki holatli enum: .success(Success) va .failure(Failure), bu yerda Failure Error protokoli bilan cheklangan. Swift Result — map, flatMap, mapError va get metodlari bilan to'liq funksional tip. get — alohida metod: natija muvaffaqiyatli bo'lsa Success qiymatini qaytaradi, Failure bo'lsa xato tashlaydi. Bu Result dan funksional va istisnoga asoslangan uslublar o'rtasida ko'prik sifatida foydalanish imkonini beradi: zanjirda map/flatMap orqali boshqaring, oxirida esa throws kodi bilan integratsiya uchun get ni do-catch orqali ishlating.

Result enum va exhaustiv switch

Swift Result generic parametrlarga ega enum, bu kompilyatorga switch yoki do-catch orqali to'liq boshqaruvni tekshirish imkonini beradi. NetworkError enum ga yangi holat qo'shsangiz, kompilyator bu holat boshqarilmagan barcha switch ifodalarida xato beradi. To'liq tekshirish (exhaustive checking) — Result ning istisnolar oldidagi asosiy afzalligi: kompilyator barcha mumkin bo'lgan xatolarni kompilyatsiya bosqichida hisobga olinishini kafolatlaydi. Buning aksincha, Swift da istisnolar kompilyator tomonidan tekshirilmaydi (faqat throws e'lon qilinadi, lekin xato turi emas).

swift
enum NetworkError: Error {
    case badURL
    case requestFailed(String)
    case decodingFailed
}

func fetchUser(id: Int) -> Result<User, NetworkError> {
    guard let url = URL(string: "https://api.example.com/users/\(id)") else {
        return .failure(.badURL)
    }
    let result = performRequest(url: url)
    switch result {
    case let .success(data):
        if let user = try? JSONDecoder().decode(User.self, from: data) {
            return .success(user)
        }
        return .failure(.decodingFailed)
    case let .failure(error):
        return .failure(.requestFailed(error.localizedDescription))
    }
}

// Switch bilan ishlatish
let result = fetchUser(id: 42)
switch result {
case .success(let user):
    showUser(user)
case .failure(.badURL):
    logError("Invalid URL")
case .failure(.requestFailed(let msg)):
    showAlert(msg)
case .failure(.decodingFailed):
    logError("Decoding error")
}

Result<Success, Failure> xatoni tip darajasida tiplashtirish imkonini beradi: fetchUser funksiyasi Result<User, NetworkError> qaytaradi, bu yerda NetworkError — uch holatli aniq enum. Chaqiruvchi tomon har bir holatni to'liq qamrab oluvchi switch orqali boshqaradi — kompilyator barcha variantlar boshqarilganligini tekshiradi. To'liq switch — Result ning istisnolar oldidagi asosiy afzalligi: kompilyator .badURL, .requestFailed yoki .decodingFailed ni boshqarishni unutmasligingizni kafolatlaydi. Istisnolar holatida kompilyator boshqarishni talab qilmaydi va tutilmagan catch(.badURL) review da osonlikcha qoldirilishi mumkin.

Kotlin da Result

Kotlin da Result<T> — standart kutubxonadan o'rnatilgan tip, muvaffaqiyat (T) yoki xatoni (Throwable) ifodalaydi. Swift dan farqli o'laroq, Kotlin da Result aniq xato turini ko'rsatishga imkon bermaydi — faqat Throwable. Bu soddalik uchun qilingan, ammo when ifodasi orqali qo'shimcha xato turi tekshirishini talab qiladi. Kotlin Result fold (har ikki holni boshqarish), getOrNull (muvaffaqiyat yoki null), getOrDefault (muvaffaqiyat yoki standart qiymat), map, recover, andThen funksiyalarini qo'llab-quvvatlaydi. Kotlin ning o'ziga xosligi: Result funksiyalar chegaralari orqali to'g'ridan-to'g'ri tarqatish uchun mo'ljallanmagan — qo'shimcha adaptatsiyasiz Android SDK yoki Kotlin Coroutines API metodlari uchun qaytariladigan tip sifatida ishlatilmaydi.

kotlin
fun parseJson(input: String): Result<JsonObject> {
    return runCatching {
        JsonParser.parseString(input).asJsonObject()
    }
}

fun validateEmail(email: String): Result<String> {
    return if (email.contains("@")) {
        Result.success(email.trim())
    } else {
        Result.failure(IllegalArgumentException("Invalid email"))
    }
}

data class SignupData(val name: String, val email: String)

fun processSignup(name: String, email: String): SignupResult {
    return validateEmail(email).fold(
        onSuccess = { validateName(name) },
        onFailure = { SignupResult.Error("Invalid email") }
    )
}

runCatching — Kotlin da qulay o'rovchi, har qanday istisnoni tutadi va Result.failure qaytaradi. validateEmail tekshirishga qarab Result.success yoki Result.failure qaytaradi. fold har ikki holni ixcham boshqaradi: Success da keyingi validatsiya funksiyasi chaqiriladi, Failure da — SignupResult.Error qaytariladi. Muhim: Kotlin Result data class maydonlarida saqlash yoki to'g'ridan-to'g'ri suspend funksiyalar chegaralari orqali uzatish uchun mo'ljallanmagan — Jetpack Compose yoki MVVM da UI holatlarini ifodalash uchun o'z sealed class laringizdan (Success/Error/Loading) foydalaning.

Dart va Flutter da Result

Dart 3.0 dan boshlab standart kutubxonada o'rnatilgan Result<T> paydo bo'ldi — ikki konstruktorli sealed class: T.ok() (muvaffaqiyat) va Error.error() (Object va StackTrace bilan xato). Dart 3.0 dan oldin Flutter dasturchilari dartz paketidan Either<L, R> yoki o'z sealed class laridan foydalanardilar. Dart da o'rnatilgan Result minimal: to'g'ridan-to'g'ri map/flatMap taqdim etmaydi — bu funksiyalar when orqali yoki extension methods yordamida amalga oshirilishi kerak. Jiddiy funksional ishlov berish uchun fpdart dan Either map, flatMap, mapLeft, fold, andThen va bind operatorlari bilan kuchliroq yechim bo'lib qolmoqda.

fpdart dan Either

Either<L, R> — fpdart paketidan chap-assotsiativ tip, bu yerda Left — xato, Right — muvaffaqiyat. O'rnatilgan Result<T> dan farqli o'laroq, Either xatoni tip parametri (L) darajasida tiplashtiradi, bu kompilyatsiya bosqichida xato turlarini farqlash imkonini beradi. fpdart paketi to'liq funksional kombinatorlar to'plamini taqdim etadi: map (Right -> Right), mapLeft (Left -> Left), flatMap (bind — ichma-ich Either), andThen (transformatsiyasiz zanjir), fold (Either dan chiqish), getOrElse (standart qiymat). Funksional yondashuv bilan Flutter ilovalari uchun Either de-fakto standart hisoblanadi.

dart
import 'dart:convert';
import 'package:fpdart/fpdart.dart';

class UserService {
    Either<AppError, User> fetchUser(String id) {
        try {
            final response = await http.get(
                Uri.parse('https://api.example.com/users/$id')
            );
            if (response.statusCode == 200) {
                final user = User.fromJson(
                    json.decode(response.body)
                );
                return Either.of(user);
            }
            return Either.left(
                AppError.serverError(response.statusCode)
            );
        } on SocketException catch (e) {
            return Either.left(AppError.networkError(e.message));
        }
    }
}

// Fold bilan ishlatish
final result = await service.fetchUser('42');
result.fold(
    (left)  => showError(left.message),
    (right) => showUser(right),
);

Either<L, R> fpdart dan — chap-assotsiativ tip: Left — xato, Right — muvaffaqiyat. fetchUser Either<AppError, User> qaytaradi, bu yerda AppError — aniq xato turlari bilan sealed class (serverError, networkError). fold har ikki holni boshqaradi: birinchi callback Left (xato) uchun, ikkinchi callback Right (muvaffaqiyat) uchun. Dart 3.0 da o'rnatilgan Result ham fold ni qo'llab-quvvatlaydi, lekin map/flatMap ni taqdim etmaydi. fpdart dan Either zanjirlari uchun map, flatMap (bind), mapLeft, andThen — xatolar kompozitsiyasi uchun to'liq funksional kombinatorlar to'plami mavjud.

Result kompozitsiyasi map va flatMap orqali

Result ning istisnolar oldidagi asosiy afzalligi — kompozitsiya. Har biri xato qaytarishi mumkin bo'lgan bir nechta operatsiyalaringiz bo'lsa, ularni map va flatMap orqali bitta zanjirda birlashtira olasiz, hech qanday ichma-ich if yoki try-catch siz. map muvaffaqiyatli qiymatni transformatsiya qiladi: Result.success(x) -> Result.success(f(x)). flatMap (shuningdek bind yoki andThen deb ataladi) — transformatsiyaning o'zi Result qaytarganda: Result.success(x) -> f(x) -> Result<Y>. Har qanday qadamda Failure yuz bersa, keyingi operatsiyalar bajarilmaydi — zanjir to'xtatiladi.

kotlin
data class UserRequest(val userId: String, val token: String)

sealed class AuthError {
    data object InvalidToken : AuthError()
    data class UserNotFound(val id: String) : AuthError()
}

typealias Outcome<T> = Either<AuthError, T>

fun validateToken(token: String): Outcome<String> =
    if (token.isNotBlank()) Either.right(token)
    else Either.left(AuthError.InvalidToken)

fun fetchProfile(userId: String): Outcome<Profile> =
    if (userId == "42") Either.right(Profile("Alice"))
    else Either.left(AuthError.UserNotFound(userId))

// flatMap orqali kompozitsiya (fpdart da andThen)
val result = validateToken("abc123")
    .flatMap { fetchProfile("42") }
    .map { it.name }
    .getOrElse { "Guest" }

println(result) // "Alice"

Zanjir: validateToken -> fetchProfile -> map name -> getOrElse "Guest". validateToken Left (InvalidToken) qaytarsa, zanjir to'xtatiladi va "Guest" qaytariladi. fetchProfile Left (UserNotFound) qaytarsa — ham "Guest". Har ikki operatsiya muvaffaqiyatli bo'lsa — profil nomi. flatMap har biri muvaffaqiyatsiz bo'lishi mumkin bo'lgan Either funksiyalarini bitta chiziqli zanjirda birlashtirish imkonini beradi. An'anaviy istisno uslubida xuddi shu kod ikkita ichma-ich try-catch yoki null tekshiruvlarini talab qilardi. getOrElse oxirida — kompozitsiyadan chiqish nuqtasi, Failure holati uchun standart qiymatni taqdim etadi.

Result vs Istisnolar: qachon nimani tanlash

Result va istisnolar — bir-birini istisno qiluvchi yondashuvlar emas. Har birining o'z qo'llanish sohasi bor va yaxshi loyihalashtirilgan mobil ilovada ikkalasi ham qo'llaniladi. Tanlov xatoning kutilgan (expected) yoki kutilmagan (unexpected) ekanligiga bog'liq. Result — biznes mantiqining bir qismi bo'lgan kutilgan xatolar uchun: noto'g'ri email, hisobda yetarli mablag' yo'qligi, so'rov limitining oshib ketishi. Istisnolar — kutilmagan tizim xatolari uchun: tarmoq uzilishi, OutOfMemoryError, NullPointerException (bo'lmasligi kerak, lekin bo'ladi).

MezonResult TypeIstisnolar (Exception/Error)
Xato turiKutilgan (biznes mantig'i)Kutilmagan (tizim)
UnumdorlikPast narx (stack ochilmasdan)Yuqori narx (stack unwinding, StackTrace olish)
Kompozitsiyamap/flatMap orqali — chiziqli zanjirlarIchma-ich try-catch — o'qish qiyin
KompilyatorTo'liq tekshirish (switch/when)Faqat Java da checked exceptions
Bajarilish oqimiTo'xtatilmaydi — xato qiymat sifatidaEng yaqin catch gacha to'xtatiladi
TestlashOson: natijani tekshirish, assert isSuccess/isErrorassertThrows va mock obyektlarini talab qiladi
Qachon ishlatishBiznes validatsiyasi, so'rov zanjirlari, formalarTarmoq uzilishi, I/O xatolar, tizim qulashlari

Amaliy qoida: agar xato ilovaning normal ish oqimining bir qismi bo'lsa (foydalanuvchi noto'g'ri email kiritdi, kirish huquqlari yetarli emas) — Result dan foydalaning. Agar xato istisno holat bo'lsa (server javob bermaydi, xotira tugadi) — istisnolardan foydalaning. Mobil ishlanmada qatlamlar chegaralarida Result (UseCase -> ViewModel) va qatlamlar ichida istisnolar (API -> Repository) — ikkala yondashuvning afzalliklarini birlashtiruvchi keng tarqalgan namuna.

Istisnolardan Result ga migratsiya strategiyasi

Mavjud istisnoga asoslangan kodni Result ga migratsiya qilish bosqichma-bosqich bo'lishi kerak. Qatlamlar chegaralaridan boshlang: throws funksiyalarining chaqiruvlarini Result { try ... } (Swift) yoki runCatching { ... } (Kotlin) bilan o'rang. Keyin Repository va UseCase metodlarining qaytariladigan tipini Result/Either bilan almashtiring, ichki implementatsiyani istisnolarda qoldirib. Oxirgi bosqichda ViewModel ni migratsiya qiling: istisnolar bilan UiState o'rniga sealed class UiState<T> (Loading, Success, Error) dan foydalaning, bu yerda Error Throwable emas, domen xatosini saqlaydi. Bosqichma-bosqich migratsiya har bir qatlamni global refaktoring qilmasdan alohida test qilish imkonini beradi.

Tez-tez so'raladigan savollar

Result Type Optional/Option dan qanday farq qiladi?

Optional (T?) qiymatning mavjudligi yoki yo'qligini ifodalaydi — nil "ma'lumot yo'q" degani, lekin sababini aytmaydi. Result (Success/Failure) nafaqat muvaffaqiyatni, balki aniq tip bilan xato sababini ham o'z ichiga oladi. Qiymatning yo'qligi normal bo'lsa Optional dan foydalaning (masalan, profilning ixtiyoriy maydoni), xato haqida ma'lumot kerak bo'lsa — Result.

throws funksiyasini Result ga qanday o'zgartirish mumkin?

Swift da Result { try throwingFunc() } dan foydalaning — Result konstruktori throws yopilishini qabul qiladi. Kotlin da — runCatching { throwingFunc() }, Result<T> qaytaradi. Dart da — Result<T>.tryCatch(() => throwingFunc()). Bu istisnoga asoslangan kodni Result zanjirlariga oson integratsiya qilish imkonini beradi.

Result da xatoni ma'lumot yo'qotmasdan qanday boshqarish mumkin?

Muvaffaqiyatli qiymatni o'zgartirmasdan xato turini transformatsiya qilish uchun mapError (Swift) yoki mapLeft (Dart/Kotlin da Either) dan foydalaning. Har ikki holni boshqarib, yagona qiymat qaytarish kerak bo'lsa — fold dan foydalaning. Zanjirni to'xtatmasdan loglash uchun onFailure (Kotlin) yoki prefiks inspection point dan foydalaning.

Kotlin da Result korutinlar bilan ishlatilishi mumkinmi?

Ha, lekin ehtiyot bilan. Kotlin Result<T> K2 compiler va refleksiya xususiyatlari tufayli to'g'ridan-to'g'ri suspend funksiyalarning qaytariladigan tipi sifatida tavsiya etilmaydi. Korutinlarda holatlarni ifodalash uchun o'z sealed class NetworkResult<T> (Success, Error, Loading) dan foydalaning. Biznes mantig'idagi kutilgan xatolar uchun Arrow dan Either kuchliroq alternativadir.

Result kontekstida fold nima?

fold — ikki callback qabul qiluvchi metod: onSuccess (muvaffaqiyatli hol uchun) va onFailure (xato holati uchun), va istalgan turdagi yagona qiymat qaytaradi. Bu switch ifodasining ekvivalenti, lekin yuqori darajali funksiya shaklida. fold — Success/Failure ni UiState, foydalanuvchi uchun string yoki boshqa Result ga aylantiradigan Result zanjirlaridan asosiy chiqish nuqtasidir.

Xulosa

  • Result Type — stack ochilmasdan kutilgan xatolarni xavfsiz boshqarish uchun generic konteyner (Success/Failure)
  • Swift da Result<Success, Failure> Failure: Error bilan switch orqali type-safe xatolar bilan to'liq tekshirishni ta'minlaydi
  • Kotlin da Result<T> muvaffaqiyat yoki Throwable ni o'raydi, runCatching — throws kodidan qulay konstruktor
  • Dart da o'rnatilgan Result<T> (Dart 3.0) va fpdart dan Either<L, R> map/flatMap bilan ilg'or kompozitsiya uchun
  • Kompozitsiya map (muvaffaqiyatni transformatsiya qilish) va flatMap (Result funksiyalari zanjiri) orqali ichma-ich try-catch ni almashtiradi
  • Result vs istisnolar: Result kutilgan biznes xatolari uchun, istisnolar kutilmagan tizim nosozliklari uchun
  • Bajarilish oqimini to'xtatmasdan aniq va test qilinadigan xato boshqaruvi uchun qatlamlar chegaralarida Result dan foydalaning

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing