3-bo‘lim
O'zgaruvchilar va turlar
var va qisqa e'lon, nol qiymatlar, son turlari va ularning chegaralari, turlar orasida o'tkazish, doimiylar va iota.
Ushbu bo‘lim mundarijasi
Go - statik turlar tili: har bir o'zgaruvchining turi kompilyatsiya paytida ma'lum bo'ladi va keyin o'zgarmaydi.
Lekin turni har doim yozish shart emas - Go uni ko'pincha o'zi aniqlaydi.
E'lon qilishning uch yo'li #
package main
import "fmt"
func main() {
var ism string = "Malika"
var yosh = 20
shahar := "Namangan"
fmt.Println(ism, yosh, shahar)
fmt.Printf("%T %T %T\n", ism, yosh, shahar)
}
Malika 20 Namangan
string int string
%T - qiymatning turini chiqaradi. Uchala shakl ham bir xil
natija beradi, farq faqat yozuvda.
| Shakl | Qayerda ishlaydi |
|---|---|
var ism string = "..." | Hamma joyda |
var yosh = 20 | Hamma joyda |
shahar := "..." | Faqat funksiya ichida |
Paket darajasida, ya'ni funksiyalardan tashqarida, faqat var yozish
mumkin:
var Versiya = "1.0" // to'g'ri
Versiya := "1.0" // xato: syntax error
Sababi oddiy: paket darajasidagi har bir qator var, const, func
yoki type bilan boshlanishi kerak.
Nol qiymatlar #
Go da e'lon qilingan, lekin qiymat berilmagan o'zgaruvchi hech qachon "chiqindi" bo'lmaydi. U doim aniq boshlang'ich qiymat oladi.
package main
import "fmt"
func main() {
var son int
var kasr float64
var matn string
var bayroq bool
fmt.Println(son, kasr, bayroq)
fmt.Printf("matn: %q (uzunligi %d)\n", matn, len(matn))
}
0 0 false
matn: "" (uzunligi 0)
| Tur | Nol qiymati |
|---|---|
int, float64 | 0 |
string | "" (bo'sh satr) |
bool | false |
Ko'rsatkich, slice, map | nil |
C da e'lon qilingan o'zgaruvchi ichida xotirada qolgan tasodifiy son bo'lardi. Bu dasturlash tarixidagi eng ko'p uchragan xatolar manbalaridan biri.
Go bu muammoni butunlay yo'q qildi. Bundan tashqari, ko'p turlar
uchun nol qiymat foydali qilib tanlangan: bo'sh sync.Mutex
darhol ishlaydi, bo'sh bytes.Buffer ga darhol yozish mumkin.
Buni "nol qiymat foydali bo'lsin" tamoyili deb atashadi.
Son turlari #
package main
import "fmt"
func main() {
var kichik int8 = 127
var katta int64 = 9223372036854775807
var musbat uint8 = 255
fmt.Println(kichik, musbat)
fmt.Println(katta)
kichik++
fmt.Println("127 ga 1 qo'shilgandan keyin:", kichik)
}
127 255
9223372036854775807
127 ga 1 qo'shilgandan keyin: -128
Oxirgi qatorga e'tibor bering. int8 eng kattasi 127; unga 1
qo'shilsa, u eng kichigiga aylanadi.
Go son chegaradan oshganda hech qanday xato bermaydi. Qiymat shunchaki aylanib ketadi.
Bu C dan meros qolgan xatti-harakat va u tezlik uchun ataylab saqlangan: har bir qo'shishda tekshiruv qo'yish dasturni sekinlashtirardi.
Himoya usuli - to'g'ri tur tanlash. Amalda deyarli har doim
oddiy int ishlatiladi: u 64 bitli tizimlarda 64 bitli bo'ladi va
uni to'ldirish deyarli imkonsiz.
| Tur | Chegara |
|---|---|
int8 / uint8 | -128..127 / 0..255 |
int16 / uint16 | -32768..32767 / 0..65535 |
int32 / uint32 | ~2.1 milliard / ~4.3 milliard |
int64 / uint64 | ~9.2 kvintillion |
int | Tizimga qarab 32 yoki 64 bit |
byte - bu uint8 ning boshqa nomi, rune esa int32 niki. Ularni
4-bo'limda ko'ramiz.
Turlar aralashmaydi #
Bu Go ni ko'p tillardan ajratib turadigan qoida:
package main
import "fmt"
func main() {
var butun int = 7
var kasr float64 = 2.5
natija := float64(butun) * kasr
fmt.Println(natija)
yosh := 25
fmt.Println("Yosh: " + fmt.Sprint(yosh))
}
17.5
Yosh: 25
Ko'p tillarda 7 * 2.5 bemalol ishlaydi. Go da esa bu xato:
var butun int = 7
var kasr float64 = 2.5
natija := butun * kasr // mismatched types int and float64
Har bir o'tkazish ko'rinadigan bo'lishi kerak: float64(butun).
Bu ko'proq yozuv talab qiladi, lekin yashirin xatolarni yo'q qiladi -
masalan, katta int64 ni float64 ga jimgina o'tkazib, aniqlikni
yo'qotib qo'yishni.
Xuddi shunday, satr va sonni + bilan qo'shib bo'lmaydi: avval
fmt.Sprint yoki strconv.Itoa bilan satrga aylantirish kerak.
Butun va kasr bo'linish #
package main
import "fmt"
func main() {
fmt.Println(7 / 2)
fmt.Println(7 % 2)
fmt.Println(7.0 / 2.0)
fmt.Println(float64(7) / float64(2))
fmt.Println(0.1 + 0.2)
birinchi := 0.1
ikkinchi := 0.2
fmt.Println(birinchi + ikkinchi)
fmt.Println(birinchi+ikkinchi == 0.3)
}
3
1
3.5
3.5
0.3
0.30000000000000004
false
Ikkita butun sonni bo'lsangiz, natija ham butun bo'ladi: 7 / 2 bu
3, 3.5 emas.
Oxirgi uch qator esa diqqat bilan qarashga arziydi. 0.1 + 0.2 aniq
0.3 chiqardi, lekin xuddi o'sha amal o'zgaruvchilar bilan
bajarilganda boshqa natija berdi.
Sabab - Go ning kam tanilgan, lekin juda muhim xususiyati: turi belgilanmagan doimiylar cheksiz aniqlikda hisoblanadi.
fmt.Println(0.1 + 0.2) da ikkala son ham doimiy. Go ularni
kompilyatsiya paytida, hech qanday yaxlitlashsiz qo'shadi va
natijada aniq 0.3 hosil bo'ladi.
birinchi := 0.1 deb yozganingizda esa vaziyat o'zgaradi: endi bu
haqiqiy float64 o'zgaruvchi. float64 sonlarni ikkilik kasr
sifatida saqlaydi, o'nlik 0.1 ni esa ikkilikda aniq yozib
bo'lmaydi - xuddi 1/3 ni o'nlikda aniq yozib bo'lmagani kabi.
Shuning uchun qo'shishda farq ko'rinib qoladi.
Bu Go ga xos emas - float64 hamma tilda shunday ishlaydi. Go ning
o'ziga xosligi - doimiylarning aniqligi.
Ikki amaliy qoida:
- Kasr sonlarni
==bilan taqqoslamang. Yuqoridagifalseaynan shuning natijasi. - Pulni hech qachon
float64da saqlamang. Eng kichik birlikni butun son sifatida saqlang - so'mni emas, tiyinni. Buni 20-bo'limdagi loyihada shunday qilamiz.
Bir vaqtda bir nechta #
package main
import "fmt"
func main() {
ism, yosh, shahar := "Husanboy", 25, "Namangan"
fmt.Println(ism, yosh, shahar)
a, b := 10, 20
a, b = b, a
fmt.Println(a, b)
var (
sarlavha = "Hisobot"
sahifa = 12
tayyor = false
)
fmt.Println(sarlavha, sahifa, tayyor)
}
Husanboy 25 Namangan
20 10
Hisobot 12 false
a, b = b, a - ikki qiymatni almashtirishning eng qisqa yo'li.
Vaqtinchalik o'zgaruvchi kerak emas.
var ( ... ) bloki esa bir nechta e'lonni bir joyga yig'adi.
Doimiylar #
package main
import "fmt"
const Soliq = 0.12
const Shahar = "Namangan"
func main() {
const MaxUrinish = 3
maosh := 5000000.0
fmt.Println("Soliq:", maosh*Soliq)
fmt.Println(Shahar, MaxUrinish)
}
Soliq: 600000
Namangan 3
const qiymati kompilyatsiya paytida ma'lum bo'lishi kerak va keyin
uni o'zgartirib bo'lmaydi.
const Soliq = 0.12 deganda Go unga tur bermaydi. U "turi
belgilanmagan doimiy" bo'lib qoladi va kerak bo'lganda mos turga
moslashadi.
Aynan shuning uchun maosh * Soliq ishlaydi, garchi maosh -
float64 bo'lsa ham. Agar const Soliq float64 = 0.12 deb yozsak,
u qat'iy float64 bo'lardi va int bilan ishlatib bo'lmasdi.
Bu kichik, lekin juda qulay imkoniyat.
iota - avtomatik raqamlash #
package main
import "fmt"
const (
Yangi = iota
Jarayonda
Bajarilgan
Bekor
)
func main() {
fmt.Println(Yangi, Jarayonda, Bajarilgan, Bekor)
const (
KB = 1 << (10 * (iota + 1))
MB
GB
)
fmt.Println(KB, MB, GB)
}
0 1 2 3
1024 1048576 1073741824
iota - const blokidagi qator raqami. U har bir yangi qatorda
bittaga oshadi va blok boshida noldan boshlanadi.
Ikkinchi blokda ifoda takrorlanadi: qator bo'sh bo'lsa, Go
yuqoridagi ifodani iota ning yangi qiymati bilan qayta hisoblaydi.
Go da enum kalit so'zi yo'q. iota bilan yozilgan const bloki -
uning o'rnini bosadigan odatiy usul.
Odatda unga o'z turi ham beriladi:
type Holat int
const (
Yangi Holat = iota
Jarayonda
Bajarilgan
)
Shunda Holat turi boshqa sonlar bilan aralashmaydi. Bu usulni
12-bo'limda, metodlar bilan birga ko'ramiz.
Turni tekshirish #
package main
import "fmt"
func main() {
qiymatlar := []any{42, "salom", 3.14, true}
for _, q := range qiymatlar {
fmt.Printf("%v -> %T\n", q, q)
}
}
42 -> int
salom -> string
3.14 -> float64
true -> bool
any - istalgan turni saqlay oladigan tur. Uni 13-bo'limda,
interfeyslar bilan birga tushunamiz.
%v - qiymatning odatiy ko'rinishi, %T esa turi.
| Shablon | Nima chiqaradi |
|---|---|
%v | Qiymat (odatiy shakl) |
%T | Tur nomi |
%d | Butun son |
%s | Satr |
%q | Qo'shtirnoq ichidagi satr |
%f | Kasr son |
%t | true yoki false |
- Bitta o'zgaruvchini uch xil usulda e'lon qiling.
- Har bir asosiy turning nol qiymatini chiqaring.
int8ni 127 dan oshirib, natijani ko'ring.intvafloat64ni ko'paytirishga urinib, xatoni o'qing.- Ularni
float64(...)bilan to'g'ri ko'paytiring. 7 / 2va7.0 / 2.0farqini ko'rsating.- Ikki o'zgaruvchini bitta qatorda almashtiring.
constqiymatini o'zgartirishga urinib ko'ring.iotabilan hafta kunlarini raqamlang.%v,%T,%qshablonlarini bitta dasturda sinang.
Xulosa #
- Uch shakl bor:
varturi bilan,vartursiz va:=. Oxirgisi faqat funksiya ichida ishlaydi. - E'lon qilingan o'zgaruvchi doim nol qiymat oladi - hech qachon chiqindi emas.
- Son chegaradan oshganda jimgina aylanadi; odatda oddiy
intishlating. - Go turlarni avtomatik o'tkazmaydi:
float64(butun)deb aniq yozish kerak. - Ikki butun sonning bo'linishi ham butun bo'ladi.
float64da0.1 + 0.2aniq0.3bermaydi - pulni tiyinda, butun son sifatida saqlang.constqiymati kompilyatsiya paytida ma'lum; turi belgilanmagan doimiy mos turga moslashadi.iota-constblokidagi avtomatik raqamlash, Go dagienumning o'rnini bosadi.
Keyingi bo'limda satrlar, runalar va baytlarni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.