04 β Funksiyalar¶
β¬ οΈ Oldingi: 03 β Boshqaruv oqimi Β· π README Β· Keyingi: 05 β To'plamlar: List, Set, Map β‘οΈ
Bu bobda: funksiya nima va nega kerakligini tushunamiz β bir bo'lak ishga nom berib, uni qayta-qayta ishlatishni o'rganamiz (DRY). Funksiyani e'lon qilish (return tipi, nom, parametrlar, tana),
void,return, qisqa arrow sintaksis (=>), uch xil parametr (positional, named{}requiredva default bilan, optional positional[]), funksiyalar birinchi-darajali qiymat ekani, anonim funksiyalar (lambda), yuqori-tartibli funksiyalar, closure (xotirali funksiya) va qisqa rekursiyani ko'ramiz. Bularning hammasi keyinchalik Flutter'da har kuni ishlatadigan poydevor β chunki Flutter'da siz funksiyalarni doimo uzatasiz (onPressed: () { ... }).
Nega funksiya kerak?¶
Tasavvur qiling, dasturingizda foydalanuvchini ismi bilan tabriklash kerak. Bir joyda yozasiz:
Keyin boshqa ekranda yana, yana boshqa joyda yana... O'ndan ortiq joyda bir xil qator. Endi rahbar aytadi: "Tabrik matnini o'zgartiraylik β 'Salom' o'rniga 'Assalomu alaykum' bo'lsin". Siz o'sha o'nta joyni topib, har birini qo'lda tuzatishingiz kerak. Bittasini unutsangiz β xato.
Bu β dasturlashdagi eng katta dushman: takrorlash. Yechim β bir bo'lak ishni bir marta yozib, unga nom berish. Mana shu nomlangan bo'lak β funksiya.
Endi o'sha o'nta joyda faqat salomla('Olim'); deb yozasiz. Matnni o'zgartirmoqchi bo'lsangiz β bitta joyni, funksiya ichini tuzatasiz, hamma joy avtomatik yangilanadi.
Bu qoidaning o'zbekcha nomi yo'q-u, ingliz dasturchilar uni DRY deydi β Don't Repeat Yourself ("o'zingni takrorlama"). Funksiya β DRY'ni amalga oshiruvchi asosiy vosita.
Funksiya yana ikki narsani beradi:
- O'qiluvchanlik.
salomla('Olim')degan qator nima qilishini nomidan tushunasiz. 50 qator kodni o'qigandan ko'ra, nomlangan funksiyalar zanjirini o'qish osonroq. - Sinash va tuzatish. Bir funksiya buzilsa, faqat o'shani tekshirasiz. Xato bir joyda yashaydi, butun dasturga tarqalmaydi.
Funksiyani mashina deb tasavvur qiling¶
Funksiyani mashina sifatida tasavvur qilish eng foydali analogiya. Sharbat qaynatgichni oling: ichiga olma solasiz (kirish), mashina ichida bir ish bo'ladi (jarayon), va tashqariga sharbat chiqadi (chiqish). Siz mashina ichida nima bo'layotganini bilishingiz shart emas β kirish va chiqishni bilsangiz yetadi.
Funksiya ham xuddi shunday: parametrlar orqali ma'lumot kiritasiz, funksiya tanasida ish bajariladi, va return orqali natija qaytadi.
Funksiyani e'lon qilish¶
Dart'da funksiyaning to'liq shakli to'rt qismdan iborat:
Bu qatorni o'ngdan chapga o'qiymiz:
| Qism | Misolda | Ma'nosi |
|---|---|---|
| Return tipi | int |
Funksiya qanday tip qaytaradi |
| Nom | qosh |
Funksiyani chaqirish uchun nom |
| Parametrlar | (int a, int b) |
Funksiya nimani qabul qiladi |
| Tana | { ... } |
Bajariladigan ish |
return a + b; qatori ikki ishni qiladi: natijani (a + b) hisoblaydi va funksiyani darhol tugatib, shu qiymatni tashqariga chiqaradi. returndan keyingi har qanday kod ishlamaydi.
Funksiyani chaqirish (call) β uning nomini yozib, qavs ichida argumentlarni berish:
π Atama farqi: funksiyani e'lon qilganda yozgan a, b β parametrlar. Funksiyani chaqirganda bergan 3, 5 β argumentlar. Parametr β bo'sh quti, argument β quti ichiga solgan haqiqiy qiymat.
void β hech narsa qaytarmaydigan funksiya¶
Ba'zi funksiyalar qiymat qaytarmaydi β ular faqat ish bajaradi (ekranga yozadi, faylga saqlaydi). Ularning return tipi β void ("hech narsa"):
void salomla(String ism) {
print('Salom, $ism!');
// return yo'q β chunki qaytaradigan qiymat yo'q
}
void aytadi: "bu funksiya foydali qiymat qaytarmaydi, uning natijasini o'zgaruvchiga olmang". salomla faqat ekranga yozish uchun chaqiriladi:
π‘ void funksiyada ham return; (qiymatsiz) yozish mumkin β bu funksiyani erta to'xtatish uchun ishlatiladi:
void tekshir(int yosh) {
if (yosh < 0) {
print('Yosh manfiy bo\'la olmaydi!');
return; // funksiyadan darhol chiqamiz, pastdagi kod ishlamaydi
}
print('Yosh: $yosh');
}
Arrow sintaksis β =>¶
Agar funksiya tanasi bitta ifodadan iborat bo'lsa (ya'ni bitta narsani hisoblab return qiladi), uni qisqa arrow ("strelka") shaklida yozish mumkin. => β bu "ushbu ifodani qaytar" degani.
Quyidagi ikki funksiya bir xil ishni qiladi:
// To'liq shakl:
int kvadrat(int n) {
return n * n;
}
// Arrow shakli β qisqaroq:
int kvadrat(int n) => n * n;
=> n * n aynan { return n * n; } degani: figurali qavs ham, return so'zi ham, nuqtali vergul ham kerak emas. Faqat bitta ifoda bo'lganda ishlaydi β ichida if, sikl yoki bir nechta qator bo'lsa, to'liq { ... } shaklini ishlatasiz.
π‘ Arrow sintaksisni hozir yaxshilab o'rganing β Flutter'da uni doimo ko'rasiz. build metodi, hodisa ishlovchilari, map callbacklar β ko'pchiligi arrow shaklida yoziladi.
Parametrlarning uch turi¶
Hozirgacha biz qosh(int a, int b) kabi oddiy (positional) parametrlarni ishlatdik. Lekin Dart'da parametrlarni berishning uch xil yo'li bor. Bu β Dart'ni Flutter uchun shunchalik qulay qiladigan eng muhim mavzulardan biri, shuning uchun har birini diqqat bilan ko'rib chiqamiz.
1. Positional parametrlar (oddiy, majburiy)¶
Bular siz allaqachon ko'rgan oddiy parametrlar. Ularni tartib bo'yicha beriladi β birinchi argument birinchi parametrga, ikkinchisi ikkinchisiga tushadi:
double bmiHisobla(double vazn, double boy) {
return vazn / (boy * boy);
}
bmiHisobla(70, 1.75); // 70 β vazn, 1.75 β boy
Tartib muhim: agar bmiHisobla(1.75, 70) deb adashtirsangiz, natija butunlay noto'g'ri bo'ladi, lekin Dart hech narsa demaydi β chunki ikkalasi ham double. Bu β positional parametrlarning kamchiligi: chaqiruvni o'qiganda qaysi raqam nima ekanini bilmaysiz.
2. Named parametrlar β {}¶
Mana shu muammoni named (nomlangan) parametrlar hal qiladi. Ularni figurali qavs {} ichiga yozasiz, va chaqirganda har bir argumentni nomi bilan berasiz:
double bmiHisobla({double vazn = 0, double boy = 0}) {
return vazn / (boy * boy);
}
bmiHisobla(vazn: 70, boy: 1.75); // endi qaysi raqam nima ekani aniq!
Named parametrlar ikki katta foyda beradi:
- O'qiluvchanlik.
bmiHisobla(vazn: 70, boy: 1.75)o'zini-o'zi tushuntiradi. Kodni o'qigan odam (yarim yildan keyin o'zingiz ham) darhol tushunadi. - Tartibdan ozodlik. Named parametrlarni istalgan tartibda berish mumkin:
bmiHisobla(boy: 1.75, vazn: 70)ham to'g'ri.
Yuqorida har bir named parametrga default qiymat berdik: {double vazn = 0}. Bu shuni anglatadiki, agar argument berilmasa, parametr o'sha default qiymatni oladi. Default qiymatli named parametr ixtiyoriy bo'ladi β chaqirganda uni tashlab ketish mumkin.
required β majburiy named parametr¶
Ba'zan named parametr kerakligini, lekin uni majburiy qilishni xohlaysiz. Buning uchun required kalit so'zini ishlatasiz:
double bmiHisobla({required double vazn, required double boy}) {
return vazn / (boy * boy);
}
bmiHisobla(vazn: 70, boy: 1.75); // β
ikkalasi ham berilgan
bmiHisobla(vazn: 70); // β Xato: 'boy' berilmagan, lekin u required
required aytadi: "bu parametr nomlangan, lekin uni tashlab ketib bo'lmaydi β albatta ber". Default qiymat va requiredni birga ishlatib bo'lmaydi (mantiqsiz β majburiy parametrning default qiymati keraksiz).
π Mana eng muhim sir: Flutter'dagi deyarli har bir widget named parametrlar bilan quriladi. Masalan, oldinda ko'radigan kodingiz shunday bo'ladi:
Bu yerda style, textAlign β hammasi named parametrlar. Mana shuning uchun named parametrlarni hozir yaxshi o'zlashtirish juda muhim: ularsiz Flutter kodini hatto o'qib ham bo'lmaydi.
3. Optional positional parametrlar β []¶
Uchinchi tur β optional positional parametrlar. Ular kvadrat qavs [] ichiga yoziladi, tartib bilan beriladi (named kabi nomi bilan emas), lekin ixtiyoriy bo'ladi:
String toliqIsm(String ism, [String? familiya]) {
if (familiya == null) {
return ism;
}
return '$ism $familiya';
}
toliqIsm('Olim'); // 'Olim'
toliqIsm('Olim', 'Karim'); // 'Olim Karim'
[String? familiya] β "familiya ixtiyoriy; berilmasa, qiymati null bo'ladi". null β "qiymat yo'q" degani; uni 06-bobda chuqur o'rganamiz. Optional positional parametrga ham default qiymat berish mumkin:
String takrorla(String matn, [int marta = 1]) {
return matn * marta;
}
takrorla('ha'); // 'ha'
takrorla('ha', 3); // 'hahaha'
π‘ Qaysi birini tanlash? Amaliy qoida: parametr bittagina va ma'nosi nomidan tushunarli bo'lsa β positional ishlating (kvadrat(5)). Bir nechta parametr bo'lsa yoki ma'no chalkash bo'lsa β named ishlating. Flutter'da deyarli har doim named ishlatiladi.
Funksiyalar β birinchi-darajali qiymat¶
Mana endi qiziq bir narsani aytamiz: Dart'da funksiya ham qiymat. Xuddi 5 yoki 'salom' kabi, funksiyani ham o'zgaruvchiga solib, boshqa funksiyaga uzatib, hatto qaytarib bo'ladi. Bunga "funksiyalar birinchi-darajali (first-class) qiymat" deyiladi.
Funksiyani o'zgaruvchiga solamiz:
int kvadrat(int n) => n * n;
void main() {
var amal = kvadrat; // funksiyani o'zgaruvchiga soldik (qavs YO'Q!)
print(amal(4)); // 16 β amal endi kvadratga ishora qiladi
}
Diqqat: var amal = kvadrat; da qavs yo'q. kvadrat (qavssiz) β funksiyaning o'zi; kvadrat(4) (qavs bilan) β funksiyani chaqirish. Bu farqni yaxshi tushunib oling.
Anonim funksiyalar (lambda)¶
Agar funksiyani faqat bir joyda ishlatmoqchi bo'lsangiz, unga nom berishning hojati yo'q. Nomsiz funksiya yozish mumkin β bunga anonim funksiya yoki lambda deyiladi.
Anonim funksiya oddiy funksiyaga o'xshaydi, faqat nomi yo'q:
// Nomli funksiya:
int kvadrat(int n) => n * n;
// Xuddi shu β anonim, o'zgaruvchiga solingan:
var kvadrat2 = (int n) => n * n;
Anonim funksiyaning ikki shakli bor β bitta ifoda uchun arrow, ko'p qator uchun figurali qavs:
var ikkilantir = (int x) => x * 2; // arrow: bitta ifoda
var tekshir = (int x) { // figurali qavs: bir nechta qator
if (x > 0) {
return 'musbat';
}
return 'musbat emas';
};
Anonim funksiyalarning haqiqiy kuchi β ularni to'g'ridan-to'g'ri boshqa funksiyaga uzatishda ko'rinadi. Mana shu yerda yuqori-tartibli funksiyalar boshlanadi.
Yuqori-tartibli funksiyalar¶
Yuqori-tartibli funksiya (higher-order function) β bu funksiyani qabul qiladigan yoki funksiyani qaytaradigan funksiya. Nomi qo'rqinchli, lekin g'oya oddiy: agar funksiya ham qiymat bo'lsa, demak uni boshqa funksiyaga argument qilib berish ham tabiiy.
Klassik misol β bir-bir funksiyani biror amalni necha marta takrorlash:
void takrorla(int marta, void Function(int) amal) {
for (int i = 0; i < marta; i++) {
amal(i); // har safar bizga berilgan funksiyani chaqiramiz
}
}
void main() {
takrorla(3, (i) {
print('Bu $i-takror');
});
}
Bu yerda void Function(int) amal β "amal parametri int qabul qilib hech narsa qaytarmaydigan funksiya" degani. takrorlaga biz anonim funksiyani uzatdik, va u uni 3 marta chaqirdi. Natija:
Funksiyani parametr sifatida qabul qilganda, uning tipini qaytim_tipi Function(parametr_tiplari) shaklida yozamiz. Yana bir misol β biror amalni qiymatga qo'llaydigan funksiya:
int qolla(int qiymat, int Function(int) amal) {
return amal(qiymat);
}
void main() {
print(qolla(5, (x) => x * x)); // 25 β kvadrat
print(qolla(5, (x) => x + 100)); // 105 β yuzta qo'shish
}
Bitta qolla funksiyasi, lekin unga turli amallarni uzatib, turli natija olamiz. Funksiyani argument qilib uzatish β kodni shunchalik moslashuvchan qiladi.
π‘ Bu nima uchun muhim? 05-bobda biz Listlarni o'rganganda .map(), .where() kabi metodlarni ko'ramiz β ularning hammasi yuqori-tartibli funksiyalar: ularga "har bir elementga nima qilish kerakligini" anonim funksiya orqali aytasiz. Masalan [1, 2, 3].map((x) => x * 2). Hozir o'rganganingiz aynan o'sha mavzuga poydevor.
Closure β xotirali funksiya¶
Endi funksiyalardagi eng "sehrli" tushunchaga keldik β closure ("yopilma"). Qo'rqmang, misol bilan oson tushuniladi.
Closure β bu o'zi tug'ilgan joydagi o'zgaruvchilarni eslab qoladigan funksiya. Ya'ni funksiya tashqi muhitdan tashqariga "chiqib ketsa" ham, o'sha muhitdagi o'zgaruvchini o'zi bilan "ko'tarib ketadi" β xuddi orqa sumkada olib yurgandek.
Klassik misol β hisoblagich (counter):
Function hisoblagichYasa() {
int count = 0; // bu o'zgaruvchi funksiya ichida tug'ildi
return () { // ichki anonim funksiyani qaytaramiz
count++; // u tashqaridagi count'ga murojaat qiladi
return count;
};
}
void main() {
var hisobla = hisoblagichYasa(); // bir marta yasaymiz
print(hisobla()); // 1
print(hisobla()); // 2
print(hisobla()); // 3
}
Bu yerda nima bo'lyapti? hisoblagichYasa() chaqirilganda, ichida count = 0 yaratiladi va ichki funksiya qaytariladi. Odatda funksiya tugagach, uning ichidagi mahalliy o'zgaruvchilar (count) yo'qoladi. Lekin bu yerda qaytarilgan ichki funksiya countni eslab qoladi β u countni o'zi bilan "ko'tarib" chiqdi.
Shuning uchun hisobla()ni har chaqirganingizda, count saqlanib turadi va ortib boradi: 1, 2, 3. Har chaqiruvda noldan boshlanmaydi β funksiya o'z holatini (state) yodida tutadi.
π Har bir hisoblagichYasa() chaqiruvi alohida count yaratadi β closurelar bir-biriga aralashmaydi:
var a = hisoblagichYasa();
var b = hisoblagichYasa();
print(a()); // 1
print(a()); // 2
print(b()); // 1 β b'ning count'i alohida, noldan boshlandi
π‘ Closure Flutter'da qayerda kerak? Juda ko'p! Flutter'da hodisa ishlovchilari (onPressed, onTap) deyarli har doim closure bo'ladi β ular o'zlari turgan joydagi o'zgaruvchilarni eslab, tugma bosilganda ishlatadi. Masalan, tugma bosilganda countni oshirib, ekranni yangilaydigan kod aynan closure asosida ishlaydi.
Scope β o'zgaruvchining ko'rinish doirasi¶
Scope (qamrov, ko'rinish doirasi) β o'zgaruvchi qayerdan ko'rinishini belgilaydi. Asosiy qoida: figurali qavs {} ichida e'lon qilingan o'zgaruvchi faqat o'sha qavs ichida yashaydi.
int globalSon = 100; // top-level: butun fayl bo'ylab ko'rinadi
void misol() {
int mahalliy = 5; // faqat misol() ichida ko'rinadi
if (mahalliy > 0) {
int ichki = 10; // faqat shu if bloki ichida ko'rinadi
print(ichki); // β
to'g'ri
}
// print(ichki); // β Xato: ichki bu yerda ko'rinmaydi
print(mahalliy); // β
to'g'ri
print(globalSon); // β
global hamma joyda ko'rinadi
}
- Top-level (global) o'zgaruvchi β funksiyalardan tashqarida, fayl darajasida e'lon qilingan; hamma joyda ko'rinadi.
- Mahalliy (local) o'zgaruvchi β funksiya yoki blok ichida; faqat o'sha doirada ko'rinadi.
π‘ Iloji boricha mahalliy o'zgaruvchi ishlating. Global o'zgaruvchilar kam bo'lgani yaxshi β ularni har joydan o'zgartirish mumkinligi xatolarga yo'l ochadi. Aytmoqchi, closurelar aynan scope qoidasi asosida ishlaydi: ichki funksiya tashqi scopedagi o'zgaruvchini ko'radi va eslab qoladi.
Rekursiya β o'zini chaqiruvchi funksiya¶
So'nggi tushuncha β rekursiya: funksiya o'z-o'zini chaqirsa. Bu g'alati ko'rinadi, lekin ba'zi masalalar uchun juda tabiiy. Klassik misol β faktorial (5! = 5 Γ 4 Γ 3 Γ 2 Γ 1 = 120):
int faktorial(int n) {
if (n <= 1) {
return 1; // to'xtash sharti β bunisiz cheksiz takrorlanadi!
}
return n * faktorial(n - 1); // funksiya o'zini chaqiradi
}
void main() {
print(faktorial(5)); // 120
}
faktorial(5) ishlashi: 5 * faktorial(4) β 5 * 4 * faktorial(3) β ... β 5 * 4 * 3 * 2 * 1.
β οΈ Har bir rekursiyada to'xtash sharti (base case) bo'lishi SHART. Bu yerda u β if (n <= 1) return 1;. Agar uni unutsangiz, funksiya o'zini cheksiz chaqiradi va dastur "stack overflow" xatosi bilan qulaydi. Rekursiyani yozganda har doim avval o'zingizdan so'rang: "bu qachon to'xtaydi?".
Flutter bilan bog'lanish¶
Bu bobda o'rganganlaringiz Flutter'ning poydevori. Flutter'da siz funksiyalarni doimiy uzatasiz. Eng oddiy misol β tugma:
Bu yerda hamma narsa tanish bo'lishi kerak:
onPressed:vachild:β named parametrlar (bu bobda o'rgandik).() { print(...); }β anonim funksiya (closure): tugma bosilganda Flutter uni chaqiradi.ElevatedButtonesa o'sha funksiyani qabul qiluvchi β ya'ni yuqori-tartibli widget.
Ya'ni: Flutter kodi sizga hozir mavhum ko'ringan bo'lsa-da, aslida siz uni allaqachon o'qiy olasiz. Funksiyalarni mukammal o'zlashtirish β Flutter sayohatingizning eng muhim qadami.
Xulosa¶
- Funksiya β nomlangan, qayta-qayta ishlatiladigan kod bo'lagi. U takrorlashni yo'qotadi (DRY) va kodni o'qiluvchan qiladi. Tasavvur: kirish β jarayon β chiqish mashinasi.
- E'lon:
qaytim_tipi nom(parametrlar) { tana }.returnnatijani qaytaradi va funksiyani tugatadi.voidβ hech narsa qaytarmaydigan funksiya. - Arrow
=>β bitta ifodali funksiya uchun qisqa shakl:int kvadrat(int n) => n * n;. - Uch xil parametr: positional
f(a, b)(tartib bilan), namedf({required a, b = 0})(nomi bilan, o'qiluvchan), optional positionalf(a, [b])(ixtiyoriy). Flutter'da deyarli doim named ishlatiladi. - Funksiyalar β birinchi-darajali qiymat: o'zgaruvchiga solinadi, uzatiladi, qaytariladi. Anonim funksiya (lambda) β nomsiz funksiya.
- Yuqori-tartibli funksiya β funksiyani qabul qiladigan/qaytaradigan funksiya (
.map/.whereuchun poydevor). - Closure β tashqi o'zgaruvchini eslab qoladigan funksiya; holatni chaqiruvlar orasida saqlaydi (Flutter callbacklarida muhim).
- Scope β o'zgaruvchining ko'rinish doirasi; mahalliyni afzal ko'ring. Rekursiya β o'zini chaqiruvchi funksiya; to'xtash sharti shart.
Keyingi bobda to'plamlarni β List, Set, Map β o'rganamiz, va aynan o'sha yerda yuqori-tartibli funksiyalarning haqiqiy kuchini (map, where, fold) ko'ramiz.
Mashqlar¶
Quyidagi mashqlarni o'zingiz yozib, dart run bilan ishga tushiring. Avval o'zingiz yeching, keyingina yechimga qarang.
kubβ bittaintqabul qilib, uning kubini (n * n * n) qaytaruvchi funksiya yozing. Avval to'liq{ return ...; }shaklida, keyin arrow shaklida yozing.salomlaβ bittaString ismqabul qilib, ekranga'Assalomu alaykum, <ism>!'chiqaruvchivoidfunksiya yozing. Uni uch xil ism bilan chaqiring.toliqIsmβism(majburiy) vafamiliya(ixtiyoriy) named parametrlar qabul qilsin. Familiya berilmasa, faqat ismni qaytarsin.requiredishlatib,ismni majburiy qiling.narxHisoblaβnarx(double) vachegirma(double, default0) named parametrlar olib, chegirmadan keyingi narxni qaytarsin.chegirmasiz vachegirmabilan chaqirib sinang.qollaβint qiymatvaint Function(int) amalqabul qilib,amal(qiymat)ni qaytaruvchi yuqori-tartibli funksiya yozing. Uni(x) => x * 10va(x) => x - 1anonim funksiyalari bilan chaqiring.hisoblagichYasaβ chaqirilganda har safar1ga ko'p son qaytaradigan closure qaytaruvchi funksiya yozing. Ikkita alohida hisoblagich yaratib, ular bir-biriga ta'sir qilmasligini ko'rsating.
β Yechimlar
1-mashq:
// To'liq shakl:
int kub(int n) {
return n * n * n;
}
// Arrow shakl:
int kub2(int n) => n * n * n;
void main() {
print(kub(3)); // 27
print(kub2(4)); // 64
}
2-mashq:
void salomla(String ism) {
print('Assalomu alaykum, $ism!');
}
void main() {
salomla('Olim');
salomla('Lola');
salomla('Karim');
}
3-mashq:
String toliqIsm({required String ism, String? familiya}) {
if (familiya == null) {
return ism;
}
return '$ism $familiya';
}
void main() {
print(toliqIsm(ism: 'Olim')); // Olim
print(toliqIsm(ism: 'Olim', familiya: 'Karim')); // Olim Karim
}
4-mashq:
double narxHisobla({required double narx, double chegirma = 0}) {
return narx - (narx * chegirma / 100);
}
void main() {
print(narxHisobla(narx: 100000)); // 100000.0
print(narxHisobla(narx: 100000, chegirma: 20)); // 80000.0
}
5-mashq:
int qolla(int qiymat, int Function(int) amal) {
return amal(qiymat);
}
void main() {
print(qolla(5, (x) => x * 10)); // 50
print(qolla(5, (x) => x - 1)); // 4
}
6-mashq:
β¬ οΈ Oldingi: 03 β Boshqaruv oqimi Β· π README Β· Keyingi: 05 β To'plamlar: List, Set, Map β‘οΈ