LevelUpGo
Multiple Return Values

Multiple Return Values

Ko'pgina tillar funksiyalarga bitta narsa qaytarishga ruxsat beradi. Go esa xohlagancha qaytarish imkonini beradi.

Bu kutilmaganda foydali. Bank orqali pul yechishni o'ylab ko'ring: sizga ham yangi balans, ham yechish ruxsat etilgan-etilmaganligi kerak. Boshqa tillarda maxsus obyekt qaytarasiz yoki xatolik (exception) tashlaysiz. Go'da esa ikkalasini ham qaytarasiz:

example.go
func withdraw(balance, amount int) (int, bool) {
	if amount > balance {
		return 0, false
	}
	return balance - amount, true
}

(int, bool) qaytish turi bu funksiya ikkita qiymat qaytarishini bildiradi. Hech qanday o'rovchi obyekt, hech qanday kortej (tuple) yo'q. Shunchaki ikkita narsani vergul bilan ajratib qaytarasiz.

Bir nechta qaytishni ushlab olish

Bir nechta qiymat qaytaradigan funksiyani chaqirganda, ularning hammasini bir vaqtda ushlaysiz:

example.go
bandwidth, ok := withdraw(100, 30)

Agar ok true bo'lsa, remaining ga ishonishingiz mumkin. Aks holda, nimadir muvaffaqiyatsiz tugagan.

Bu result, ok andazasi Go'da hamma joyda uchraydi. Hatto standart kutubxona ham undan foydalanadi. Masalan, strconv.Atoi satrni butun songa aylantiradi va ham son, ham xatolikni qaytaradi:

example.go
num, err := strconv.Atoi("42")   // num = 42, err = nil
num, err := strconv.Atoi("nope") // num = 0, err = error

Bu andazani xarita (map) qidiruvlari, tur tasdiqlari (type assertions), va keyinroq kanal qabul qilishlarida ko'rasiz. Hoziroq unga ko'nikib oling.

Buni qachon ishlatish kerak

Chaqiruvchiga ham "nima bo'ldi", ham "ishladimi" ikkalasini bilish kerak bo'lganda bir nechta qiymat qaytaring:

example.go
func divide(a, b float64) (float64, bool) {
	if b == 0 {
		return 0, false
	}
	return a / b, true
}

result, ok := divide(10, 3)

>_ Exercise

Siz chipta bron qilish tizimini yaratyapsiz. bookSeats(available, requested int) (int, bool) nomli funksiya yozing, bunda available — qolgan o'rindiqlar soni, requested esa kimdir bron qilmoqchi bo'lgan soni.

Agar bron noto'g'ri bo'lsa, 0, false qaytaring. Bron quyidagi hollarda noto'g'ri hisoblanadi: requested nol, manfiy, yoki available dan katta bo'lsa.

Agar bron to'g'ri bo'lsa, so'ralgan o'rindiqlarni mavjud o'rindiqlardan ayiring va natijani true bilan qaytaring.

Misollar:

CHAQIRUVQAYTARADINEGA
bookSeats(50, 10)40, true10 tasi bron qilingandan keyin 40 o'rin qoladi
bookSeats(5, 20)0, falseyetarli o'rin yo'q
bookSeats(10, 10)0, trueaynan shu miqdorni bron qilish yaxshi, 0 qoladi
bookSeats(10, 0)0, falsenol haqiqiy bron emas
bookSeats(10, -1)0, falsemanfiy haqiqiy bron emas

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Go funksiyalari bir nechta qiymat qaytarishi mumkin. Ikkinchi qiymat odatda ishlar yaxshi ketganini bildiradi. Uni nima deb nomlashingiz uning turiga bog'liq:

example.go
// bool → "ok" dan foydalaning
remaining, ok := bookSeats(50, 10)

// error → "err" dan foydalaning
num, err := strconv.Atoi("42")

NEXT UP

The Clean Switch

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

Multiple Return Values

Ko'pgina tillar funksiyalarga bitta narsa qaytarishga ruxsat beradi. Go esa xohlagancha qaytarish imkonini beradi.

Bu kutilmaganda foydali. Bank orqali pul yechishni o'ylab ko'ring: sizga ham yangi balans, ham yechish ruxsat etilgan-etilmaganligi kerak. Boshqa tillarda maxsus obyekt qaytarasiz yoki xatolik (exception) tashlaysiz. Go'da esa ikkalasini ham qaytarasiz:

example.go
func withdraw(balance, amount int) (int, bool) {
	if amount > balance {
		return 0, false
	}
	return balance - amount, true
}

(int, bool) qaytish turi bu funksiya ikkita qiymat qaytarishini bildiradi. Hech qanday o'rovchi obyekt, hech qanday kortej (tuple) yo'q. Shunchaki ikkita narsani vergul bilan ajratib qaytarasiz.

Bir nechta qaytishni ushlab olish

Bir nechta qiymat qaytaradigan funksiyani chaqirganda, ularning hammasini bir vaqtda ushlaysiz:

example.go
bandwidth, ok := withdraw(100, 30)

Agar ok true bo'lsa, remaining ga ishonishingiz mumkin. Aks holda, nimadir muvaffaqiyatsiz tugagan.

Bu result, ok andazasi Go'da hamma joyda uchraydi. Hatto standart kutubxona ham undan foydalanadi. Masalan, strconv.Atoi satrni butun songa aylantiradi va ham son, ham xatolikni qaytaradi:

example.go
num, err := strconv.Atoi("42")   // num = 42, err = nil
num, err := strconv.Atoi("nope") // num = 0, err = error

Bu andazani xarita (map) qidiruvlari, tur tasdiqlari (type assertions), va keyinroq kanal qabul qilishlarida ko'rasiz. Hoziroq unga ko'nikib oling.

Buni qachon ishlatish kerak

Chaqiruvchiga ham "nima bo'ldi", ham "ishladimi" ikkalasini bilish kerak bo'lganda bir nechta qiymat qaytaring:

example.go
func divide(a, b float64) (float64, bool) {
	if b == 0 {
		return 0, false
	}
	return a / b, true
}

result, ok := divide(10, 3)

>_ Exercise

Siz chipta bron qilish tizimini yaratyapsiz. bookSeats(available, requested int) (int, bool) nomli funksiya yozing, bunda available — qolgan o'rindiqlar soni, requested esa kimdir bron qilmoqchi bo'lgan soni.

Agar bron noto'g'ri bo'lsa, 0, false qaytaring. Bron quyidagi hollarda noto'g'ri hisoblanadi: requested nol, manfiy, yoki available dan katta bo'lsa.

Agar bron to'g'ri bo'lsa, so'ralgan o'rindiqlarni mavjud o'rindiqlardan ayiring va natijani true bilan qaytaring.

Misollar:

CHAQIRUVQAYTARADINEGA
bookSeats(50, 10)40, true10 tasi bron qilingandan keyin 40 o'rin qoladi
bookSeats(5, 20)0, falseyetarli o'rin yo'q
bookSeats(10, 10)0, trueaynan shu miqdorni bron qilish yaxshi, 0 qoladi
bookSeats(10, 0)0, falsenol haqiqiy bron emas
bookSeats(10, -1)0, falsemanfiy haqiqiy bron emas

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Go funksiyalari bir nechta qiymat qaytarishi mumkin. Ikkinchi qiymat odatda ishlar yaxshi ketganini bildiradi. Uni nima deb nomlashingiz uning turiga bog'liq:

example.go
// bool → "ok" dan foydalaning
remaining, ok := bookSeats(50, 10)

// error → "err" dan foydalaning
num, err := strconv.Atoi("42")

NEXT UP

The Clean Switch