Published on

Swift-da Tuple-lardan qanday foydalanish kerak

Authors

Va biz qaytib keldik, hammaga salom! Umid qilamanki, oldingi video sizlarni qo'rqitib yubormadi. Oldingi videoda biz optional nima ekanligini o'rgandik va optionallarni o'z ichiga olgan juda ko'plab funksiyalar yozdik. Ammo hozirgacha ushbu pleylistda biz yaratgan barcha funksiyalar har doim faqat bitta turdagi ma'lumotni qaytargan edi. Aslida, ilovangizda ba'zan bittadan ko'proq ma'lumotni qaytarishni xohlaydigan holatlar bo'ladi — masalan, sizga ikki, uch yoki o'n xil ma'lumotni qaytaradigan funksiya kerak bo'lishi mumkin. Shuning uchun Swift-da tuple deb ataladigan narsadan foydalanamiz — bu, asosan, ichida bir nechta ma'lumot bo'lagini saqlaydigan bitta ma'lumot bo'lagi. Mana shu — tuple, va biz buni aynan ushbu videoda o'rganamiz.


Hammaga yana xush kelibsiz! Biz ushbu pleylist bo'yicha juftakka ilgarilab ketmoqdamiz — bilaman, mavzular biroz qiyinlashib bormoqda, ammo xavotir olmang, vaqt o'tishi bilan siz bularning hammasini tushunib olasiz. Birinchi marta qilganingizda murakkab tuyulishi mumkin, ammo besh-o'n marta qaytarib ishlatganingizdan keyin, bu sizga ancha qulay bo'lib qoladi.

Masalan, ikki video oldin biz funksiyalar yozdik, oldingi videoda esa yana ko'plab funksiyalar yozdik, va ushbu videoda biz yanada murakkabroq funksiyalar yozamiz — ammo funksiya yozish sintaksisi sizlar uchun, menimcha, allaqachon biroz qulayroq bo'lib qolgan bo'lishi kerak. Oldingi video ancha qiyin edi, chunki biz optionallar haqida gaplashdik, va optionallar yaxshi Swift kodi yozish uchun juda muhim. Ammo ushbu videodagi kod, aslida, oldingisidan ancha osonroq bo'lishi kerak — shuning uchun umid qilaman, bu safar sizlar uchun biroz "dam olish" bo'ladi.

Biz tuplelar haqida gaplashamiz. Hozirgacha ushbu kursda funksiyadan biror narsa qaytarganimizda, biz har doim faqat bitta qiymat qaytargan edik. Ammo biz bir nechta qiymatga ega bo'lgan tupleni ham qaytarishimiz mumkin. Demak, faqat bitta narsani qaytarish o'rniga, biz ikki, uch, besh, o'n narsani qaytarishimiz mumkin.


Yangi playground sahifa

Navigator-da o'ng tugmani bosib, yangi playground sahifa yaratamiz va unga Tuples deb nom beramiz. Standart kodni o'chirib, kod yozishni boshlaymiz.

Avval username nomli, string turidagi o'zgaruvchi yaratamiz va unga, aytaylik, "hello" qiymatini beramiz. Keyin userIsPremium nomli, Bool turidagi o'zgaruvchi yaratamiz va falsega tenglashtiramiz, va userIsNew nomli, yana Bool turidagi o'zgaruvchini yaratib, truega tenglashtiramiz:

var username: String = "hello"
var userIsPremium: Bool = false
var userIsNew: Bool = true

Endi getUsername nomli funksiya yaratamiz. Bu funksiya string qaytaradi, va biz usernameni qaytaramiz:

func getUsername() -> String {
    return username
}

Endi getUserIsPremium nomli yana bir funksiya yaratamiz. Bu bizga Boolean qaytaradi, va biz userIsPremiumni qaytaramiz. Yana eslatib o'taman: Swift-da, agar funksiyadan faqat bitta narsa qaytarayotgan bo'lsangiz va bu bitta qatorli kod bo'lsa, return so'zini yozish shart emas — kompilyator biz bu qiymatni qaytarmoqchi ekanligimizni o'zi tushunadi:

func getUserIsPremium() -> Bool {
    userIsPremium
}

Bitta funksiyadan bir nechta qiymatni qaytarish muammosi

Endi getUserInfo nomli funksiya yarataylik — bu, aytaylik, ilovamizdan bevosita chaqiriladigan funksiya, va biz unda har ikkala qiymatni ham olishni xohlaymiz. Shunday qilib, name nomli konstanta yaratib, getUsername()ga tenglashtiramiz, va isPremium nomli konstanta yaratib, getUserIsPremium()ga tenglashtiramiz. Endi biz ikkalasi bilan ham biror narsa qilishni xohlaymiz.

Ammo oldingi yozgan kodimizga ko'ra muammo shundaki: agar shu funksiyadan biror narsa qaytarsak, biz faqat bitta elementni qaytarishimiz mumkin — ya'ni men ikkalasini birga qaytara olmayman. Bu, albatta, ilovamizni kengaytirishga harakat qilganimizda muammo tug'diradi.

Men nameni qaytarishim mumkin, yoki agar Boolean kerak bo'lsa isPremiumni qaytarishim mumkin — ammo bu funksiyadan ikkalasini birga qanday qaytarish mumkin? Buning yechimi — tuple yaratish.

Hozircha, getUserInfo faqat string qaytaradi deb yozaylik — bu yerga izoh qo'yamiz: "bitta qaytarish turi bilan cheklangan", va nameni qaytaramiz:

// bitta qaytarish turi bilan cheklangan
func getUserInfo() -> String {
    let name = getUsername()
    let isPremium = getUserIsPremium()

    return name
}

Garchi biz isPremium uchun ham qiymat olgan bo'lsak ham, biz buni shu funksiyadan qaytarib bo'lmaydi.


Tuple yaratish

Endi getUserInfo2 nomli boshqa bir funksiya yarataylik, va bu safar uning qaytarish turini ikkita narsani qaytaradigan qilib o'zgartiramiz. Buning uchun avval String deb yozamiz, so'ngra qaytaradigan ikkinchi narsa — bu Boolean bo'lgan isPremium, shuning uchun Bool deb yozamiz. Endi kompilyatorga bu ikkisi bitta qaytarishning qismi ekanligini bildirish uchun, ularni qavslar ichiga olamiz.

Shunday qilib, bu funksiya endi bir string qiymat va bir Boolean qiymatni qaytarishni kutadi, va u bizga buni hali bajarmaganimizni ko'rsatib turadi. Buni tuzatish uchun, biz buni ham qavslar ichiga olamiz va bir string qiymat hamda bir Boolean qiymatni birga qaytaramiz:

func getUserInfo2() -> (String, Bool) {
    let name = getUsername()
    let isPremium = getUserIsPremium()

    return (name, isPremium)
}

Endi getUserInfo2ni chaqirganimda, men ikkala ma'lumotni ham birga qaytarib olishim mumkin.

Tuple bir nechta ma'lumot bo'lagini birlashtirishi mumkin.


Tuple turidagi o'zgaruvchi yoki konstanta yaratish

Endi bizda ikkalasi bir joyda mavjud. Xuddi shu narsani funksiyada qilganimizdek, biz buni konstanta yoki o'zgaruvchida ham qilishimiz mumkin. Masalan, agar men userData1 nomli o'zgaruvchi yaratib, uni usernamega tenglashtirsam — bu string turiga tegishli bo'ladi:

var userData1 = username

Men shuningdek userData2 nomli o'zgaruvchini ham yaratib, uni String va Booldan iborat tuple qilib belgilashim, va username va userIsPremiumga tenglashtirishim mumkin:

var userData2: (String, Bool) = (username, userIsPremium)

Demak, oldingi bir necha videoda biror narsani string turiga tegishli deb e'lon qilganimizdek, biz endi biror narsani string va Boolean'dan iborat tuple turiga tegishli deb ham e'lon qilishimiz mumkin.

Bu bizga bir nechta qiymatni guruhlashga imkon beradi, va biz faqat ikki qiymat bilan cheklanmaymiz — bundan ko'proq ham qilishimiz mumkin. Bizda uchinchi narsa — userIsNew ham bor edi, shuning uchun biz shu tuple-ga yana bir Boolean qo'shib, userIsNewni ham kiritishimiz mumkin. Shu tarzda, bu tuple-larni tobora ko'proq va ko'proq ma'lumot bo'lagi bilan kengaytirib borishimiz mumkin.


Tuple elementlariga indeks orqali murojaat qilish

Endi sizlarga tezroq bir narsani ko'rsatib o'taman. Aytaylik, info1 nomli konstanta yaratamiz va uni getUserInfo2()ning natijasiga tenglashtiramiz:

let info1 = getUserInfo2()

getUserInfo2 bizga string va Booldan iborat tuple qaytaradi — agar Option tugmasini bosib shu ustiga bossangiz, aynan shuni ko'rasiz, bu bizda yuqorida yozganimiz bilan bir xil.

Ammo agar men buni kodimda olib, undan string qiymatini, ya'ni name qiymatini olishni xohlasam-chi? Buning uchun name1 nomli konstanta yaratib, uni info1ga tenglashtirib, so'ngra nuqta qo'yib qarayman — bu yerda tuple ekanligini ko'rsatuvchi .0 va .1 degan tugatish (completion) variantlari paydo bo'ladi.

Bular nimani bildiradi? Bular info1 ichidagi ma'lumot bo'laklariga murojaat qilish uchun ishlatiladi, va ular xronologik tartibda joylashgan. Agar siz massivlar (array) bilan tanish bo'lsangiz — men keyinroq shu seriyada massivlarni ham ko'rib chiqaman — massivlar 0-indeksdan boshlanadi va keyin o'sib boradi: birinchi element — nol, ikkinchi element — bir, uchinchi element — ikki, to'rtinchi element — uch, va hokazo.

Demak, bu bizga shuni bildiradi: 0 — tuple ichidagi birinchi element bo'lishi kerak. getUserInfo2ga qaytib qarasak: birinchi element — string, ikkinchi element — Boolean. Shuning uchun:

let info1 = getUserInfo2()

let name1 = info1.0

Bu yerda name1string. Va biz ikkinchi elementni, ya'ni Boolean'ni olishga harakat qilib ko'rsak:

let isPremium1: String = info1.1
// Xatolik: Cannot convert value of type 'Bool' to specified type 'String'

Kompilyator bizga xatolik beradi, chunki biz Boolean qiymatini string turiga tenglashtirishga urinmoqdamiz.

Rostini aytsam, mendan so'rasangiz, bu — biroz chalkash usul: har safar nol va birni yozib, "aslida nol indeksda nima bor edi" deb o'ylab o'tirish noqulay. Tasavvur qiling: agar bu kod bir faylda, foydalanish joyi esa butunlay boshqa faylda bo'lsa, siz buni chaqirganingizda butunlay chalkashib qolishingiz mumkin — "voy, men birinchi nimani qo'ygan edim, ikkinchi nimani qo'ygan edim" deb. Va ayniqsa, agar tuple kattaroq bo'lsa — masalan, bizning userData2imiz kabi — endi qaysi raqam nimani bildirishini aniqlash juda chalkash bo'lib qoladi.


Tuple elementlariga nom berish

Keling, buni tezda hal qilaylik. userInfo3 nomli yana bir funksiya yaratamiz, va bu safar har bir elementga parametr nomi beramiz: birinchisi — string turidagi name, ikkinchisi — Bool turidagi isPremium. Xuddi o'zgaruvchi va konstantalarni nomlaganimizdek, biz tuple ichidagi elementlarni ham shunday nomlay olamiz:

func getUserInfo3() -> (name: String, isPremium: Bool) {
    let name = getUsername()
    let isPremium = getUserIsPremium()

    return (name, isPremium)
}

Endi, agar men info2 nomli konstanta yaratib, uni getUserInfo3()ga tenglashtirsam:

let info2 = getUserInfo3()

Yana, Option tugmasini bosib shu ustiga bossam — bu ham string va Booldan iborat tuple, faqat bu safar parametrlarga nom berilgan. Endi agar men name2 nomli konstanta yaratib, uni info2ga tenglashtirsam, va nuqta qo'ysam — endi menda nol va bir o'rniga, bu konstantalarning haqiqiy nomlari chiqadi: men shunchaki .name yoki .isPremium deb yozishim mumkin, va bu .0, .1 yozishdan ancha o'qilishi oson:

let name2 = info2.name
let premium2 = info2.isPremium

Ikkalasi ham — ya'ni info1.0 ham, info2.name ham — ishlaydi; ba'zi dasturchilar qisqaroq yozish uchun raqamli usulni ishlatadi, chunki bu kamroq kod yozishni talab qiladi. Ammo men aytardim, nomlangan usul ko'pchilik loyihalarda ancha o'qilishi oson va afzalroq bo'ladi.


Yakuniy misol — tuple-ni butunligicha parametr sifatida uzatish

Yakunlashdan oldin, oxirgi bir misol ko'raylik. getUserInfo4 nomli yana bir funksiya yarataylik — bu safar biz har ikkala qiymatni ham olamiz, shuningdek isNew uchun ham qiymat olamiz. Aslida bizga bu funksiyalarning o'ziga ham ehtiyoj yo'q — biz bu o'zgaruvchilarga to'g'ridan-to'g'ri murojaat qilishimiz mumkin. Shunday qilib, biz username, userIsPremium va userIsNewni qaytaramiz, va bu funksiya endi name, isPremium va isNewni — barchasi Bool turida — qaytaradi:

func getUserInfo4() -> (name: String, isPremium: Bool, isNew: Bool) {
    return (username, userIsPremium, userIsNew)
}

Endi, aytaylik, kodimda doSomethingWithUserInfo nomli yana bir funksiya bor. Men getUserInfo4ni chaqirib, foydalanuvchi ma'lumotini olganimdan so'ng, shu ma'lumot bilan biror ish qilishni xohlayman. Shuning uchun, men shu funksiyaga info nomli parametr qo'shib, uning turini aynan getUserInfo4dan kelayotgan tur bilan bir xil qilib belgilashim mumkin — shunday qilib, men butun bu ma'lumotni shu funksiyaga bitta parametr sifatida uzata olaman:

func doSomethingWithUserInfo(info: (name: String, isPremium: Bool, isNew: Bool)) {
    print(info.name, info.isPremium, info.isNew)
}

Endi, misol uchun, men info nomli konstanta yaratib, uni getUserInfo4()ga tenglashtirishim mumkin, va bu tur aynan doSomethingWithUserInfo funksiyasi kutgan tur bilan bir xil bo'lgani uchun, men endi doSomethingWithUserInfoni chaqirib, unga shu infoni uzatishim mumkin:

let info = getUserInfo4()

doSomethingWithUserInfo(info: info)

Xulosa

Mana shu — tuple nima ekanligi. Bu bizga, asosan, bir nechta ma'lumot bo'lagini birlashtirish yoki guruhlashga imkon beradi. Nazariy jihatdan, biz buni cheksiz kengaytirishimiz mumkin — ikki ma'lumotli tuple ham, o'n ma'lumotli tuple ham, yuz ma'lumotli tuple ham bo'lishi mumkin. Ammo ushbu videoning oxirida men ta'kidlab o'tmoqchi bo'lgan narsa shu: bunday qilish juda chalkash va og'ir bo'lib ketishi mumkin. Tasavvur qiling, sizda shunday 50 ta tuple bor — bu ilovangiz bo'ylab ko'chirib-joylashtirib yurishingiz kerak bo'lgan juda ko'p kod bo'lagi degani, va bu siz, dasturchi uchun ham juda chalkash bo'lib qoladi, chunki kodning o'zi juda uzun va og'ir bo'lib ketadi.

Demak, garchi biz buni cheksiz kengaytira olsak ham, buning yaxshiroq yo'llari mavjud, va aynan shuni keyingi bir necha videoda ko'rib chiqamiz. Buning yechimi — asosan, o'zimizning turlarimizni yaratishdir. Biz ichida bir nechta ma'lumot bo'lagi bo'lgan maxsus turlarni yaratishimiz mumkin, va buni keyingi bir necha videoda qilamiz.

Shunday qilib, ushbu videoda men sizlarga tuple-larga shunchaki qisqa kirish qilib bermoqchi edim. Bular juda foydali: agar sizda ikki alohida ma'lumot bo'lagi bo'lsa, ularni osongina birlashtirib, bitta ma'lumot sifatida olib yurishingiz mumkin. Va biz buni kengaytirishimiz mumkin, ammo oxir-oqibat biz o'zimizning ma'lumot turlarimizni yaratishni boshlaymiz — bu turlar, asosan, bir nechta ma'lumot bo'lagini bitta tur ichiga jamlaydi.

Buni keyingi bir necha videoda qilamiz — ularni tartib bilan tomosha qilishni qattiq tavsiya qilaman. Tomosha qilganingiz uchun rahmat! Men — Nick, bu Swiftful Thinking, keyingi videoda ko'rishamiz!

Buy mea coffee