- Published on
Swiftda Result Type
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
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.