Published on

Swiftda Result Type

Authors

Result β€” Swift ning muvaffaqiyat yoki xatoni ifodalovchi enum turi. Optional faqat "qiymat bor yoki yo'q" desa, Result xato haqida aniq ma'lumot ham beradi. U Result<Success, Failure> ko'rinishida β€” Success muvaffaqiyat qiymati turi, Failure xato turi.

Result qachon kerak? β€” Callback-based funksiyalarda (masalan, tarmoq so'rovlari) throws ishlatib bo'lmaydi. Result shu holatlarda xatoni xavfsiz uzatish imkonini beradi. Bundan tashqari, map(), flatMap(), get() kabi metodlar bilan ishlash juda qulay.

Asosiy tushuncha

Quyida Result ni qaytaradigan funksiya va uni switch bilan tekshirish ko'rsatilgan. .success() muvaffaqiyat qiymatni, .failure() xato qiymatni o'rab oladi.

// ═══════════════════════════════════════
//  RESULT β€” ikki holat: muvaffaqiyat yoki xato
// ═══════════════════════════════════════
// Result<Success, Failure> β€” Success: muvaffaqiyat turi, Failure: xato turi

// O'z xato turimiz
enum TarmoqXatosi: Error {
    case urlXato
    case serverXatosi(kod: Int)
    case ma'lumotYo'q
    case dekodlashXatosi
}

// Funksiya Result qaytaradi
func foydalanuvchiniYukla(id: Int) -> Result<String, TarmoqXatosi> {
    if id <= 0 {
        return .failure(.urlXato)
    }
    if id > 100 {
        return .failure(.serverXatosi(kod: 404))
    }
    return .success("Foydalanuvchi #\(id)")
}

// Ishlatish β€” switch bilan
let natija = foydalanuvchiniYukla(id: 42)

switch natija {
case .success(let ism):
    print("Topildi: \(ism)")        // "Topildi: Foydalanuvchi #42"
case .failure(let xato):
    switch xato {
    case .urlXato:
        print("URL noto'g'ri")
    case .serverXatosi(let kod):
        print("Server xatosi: \(kod)")
    case .ma'lumotYo'q:
        print("Ma'lumot yo'q")
    case .dekodlashXatosi:
        print("JSON xatosi")
    }
}

Result bilan ishlash usullari

Result da bir nechta qulay metodlar bor: get() β€” success qiymatini oladi (xato bo'lsa throw qiladi), map() β€” success qiymatini o'zgartiradi (failure ga tegmaydi), flatMap() β€” boshqa Result qaytaradigan transformatsiya.

let natija: Result<Int, TarmoqXatosi> = .success(42)

// ═══════════════════════════════════════
//  get() β€” success qiymatini olish (throw qilishi mumkin)
// ═══════════════════════════════════════
do {
    let qiymat = try natija.get()  // 42
    print("Qiymat: \(qiymat)")
} catch {
    print("Xato: \(error)")
}

// ═══════════════════════════════════════
//  map() β€” success qiymatini o'zgartirish
// ═══════════════════════════════════════
let matnga: Result<String, TarmoqXatosi> = natija.map { son in
    "Natija: \(son)"  // Int β†’ String
}
// .success("Natija: 42")

// ═══════════════════════════════════════
//  flatMap() β€” Result qaytaradigan transformatsiya
// ═══════════════════════════════════════
func ikkilantirish(_ son: Int) -> Result<Int, TarmoqXatosi> {
    if son > 50 {
        return .failure(.ma'lumotYo'q)
    }
    return .success(son * 2)
}

let ikkilangan = natija.flatMap(ikkilantirish)
// .success(84)

// ═══════════════════════════════════════
//  mapError() β€” xato turini o'zgartirish
// ═══════════════════════════════════════
let umumiyXato: Result<Int, Error> = natija.mapError { xato in
    xato as Error  // TarmoqXatosi β†’ Error
}

Completion Handler da Result

// ═══════════════════════════════════════
//  ESKI USUL β€” ikki optional parametr
// ═══════════════════════════════════════
func eskiUsul(completion: (String?, Error?) -> Void) {
    // Muammo: ikkalasi ham nil yoki ikkalasi ham qiymatli bo'lishi mumkin
    completion("natija", nil)  // yoki completion(nil, xato)
}

// ═══════════════════════════════════════
//  YANGI USUL β€” Result bilan
// ═══════════════════════════════════════
func yangiUsul(completion: (Result<String, Error>) -> Void) {
    // Faqat BITTA holat β€” yo muvaffaqiyat yo xato
    completion(.success("natija"))
    // yoki
    // completion(.failure(TarmoqXatosi.serverXatosi(kod: 500)))
}

// Chaqirish
yangiUsul { natija in
    switch natija {
    case .success(let qiymat):
        print("Muvaffaqiyat: \(qiymat)")
    case .failure(let xato):
        print("Xato: \(xato)")
    }
}

throws dan Result ga o'tkazish

// ═══════════════════════════════════════
//  Result(catching:) β€” throws ni Result ga aylantirish
// ═══════════════════════════════════════
func xavfliHisoblash() throws -> Int {
    // ... xato bo'lishi mumkin
    return 42
}

// throws β†’ Result
let natija = Result { try xavfliHisoblash() }
// .success(42) yoki .failure(error)

🎯 Topshiriq

enum BankXatosi: Error yarating (mablag'Yetarli emas, hisobTopilmadi, limitOshdi). pulOtkazish(summa:) funksiyasi Result<String, BankXatosi> qaytarsin. Har xil summalar bilan chaqirib, switch bilan natijani ko'rsating. map() bilan natijani formatlang.

Buy mea coffee