Tarkibga o'tish

Goda asosiy ma'lumot turlari

Ma'lumot turi qiymat nimani ifodalashi va u bilan qanday amallar bajarish mumkinligini belgilaydi. Masalan, int butun sonni, string matnni, bool esa mantiqiy toifani anglatadi.

Tasavvur qiling, dastur foydalanuvchining ismi, yoshi va tizimga kirgan yoki kirmaganini saqlashi kerak. Har bir qiymatning vazifasi boshqa bo'lgani uchun ularning turlari ham boshqa bo'ladi:

main.go
package main

import "fmt"

func main() {
    ism := "Ali"        // string
    yosh := 25           // int
    tizimgaKirdi := true // bool

    fmt.Println(ism, yosh, tizimgaKirdi)
}

Natija:

Ali 25 true

Bu misolda yosh bilan arifmetik amal bajarish, ism ni matn sifatida ishlash, tizimgaKirdi orqali esa biror shartni tekshirish mumkin.

Ma'lumot turi nima uchun kerak?

Go statik turli til. Har bir o'zgaruvchining turi kod kompilyatsiya qilinayotgan paytda aniqlanadi. Bu kompilyatorga noto'g'ri amallarni dastur ishga tushishidan oldin topishga yordam beradi.

Masalan, butun son saqlaydigan o'zgaruvchiga matn berib bo'lmaydi:

var yosh int = 25
// yosh = "yigirma besh" // string qiymatni int o'zgaruvchiga berib bo'lmaydi

Go boshlang'ich qiymatga qarab turni o'zi aniqlashi ham mumkin:

ism := "Ali" // string
yosh := 25   // int
narx := 19.5 // float64

Tur nomi yozilmagan bo'lsa ham, har bir o'zgaruvchi aniq bir turga ega. Kompilyator boshlang'ich qiymatga qarab aniqlaydi. Turni %T yordamida ko'rish mumkin:

main.go
1
2
3
4
5
6
7
8
package main

import "fmt"

func main() {
    qiymat := 97
    fmt.Printf("Qiymat: %v, turi: %T\n", qiymat, qiymat)
}

Natija:

Qiymat: 97, turi: int

%v qiymatni, %T esa uning turini chiqaradi.

Butun sonlar

Butun sonlarda kasr qismi bo'lmaydi: -12, 0, 25. Kundalik hisob-kitoblarda ko'pincha int ishlatiladi:

var yosh int = 25
var harorat int = -5
var talabalarSoni = 30 // Go bu qiymatni int deb aniqlaydi

int turi kompyuter arxitekturasiga qarab 32 yoki 64 bit bo'ladi. Oddiy hisoblarda, yosh, mahsulot soni va indeks kabi qiymatlar uchun odatda int tanlanadi.

Aniq o'lchamdagi ishorali sonlar

Ishorali (signed) turlar musbat, manfiy va nol qiymatlarni saqlaydi:

Tur O'lchami Qiymatlar oralig'i
int8 8 bit -128 dan 127 gacha
int16 16 bit -32 768 dan 32 767 gacha
int32 32 bit -2 147 483 648 dan 2 147 483 647 gacha
int64 64 bit -9 223 372 036 854 775 808 dan 9 223 372 036 854 775 807 gacha

Ishorasiz butun sonlar

Ishorasiz (unsigned) turlar manfiy qiymat saqlamaydi:

Tur O'lchami Qiymatlar oralig'i
uint8 8 bit 0 dan 255 gacha
uint16 16 bit 0 dan 65 535 gacha
uint32 32 bit 0 dan 4 294 967 295 gacha
uint64 64 bit 0 dan 18 446 744 073 709 551 615 gacha

uint ham kompyuter arxitekturasiga qarab 32 yoki 64 bit bo'ladi. Umumiy hisob-kitoblarda int qulayroq, chunki Go har xil turlarda matematik amallarni bajarmaydi.

Warning

Tur sig'dira oladigan oraliqdan chiqish overflow deb ataladi. Son uchun yetarli oraliqqa ega turni tanlash muhim.

main.go
1
2
3
4
5
6
7
8
package main

import "fmt"

func main() {
    var son int8 = 128 // int8 chegarasidan katta son shu sabab xatolik sodir bo'ladi
    fmt.Println(son)
}

Natija:

.\main.go:6:17: cannot use 128 (untyped int constant) 
as int8 value in variable declaration (overflows)

Kasrli sonlar

Kasr qismi bor sonlar uchun float32 va float64 ishlatiladi:

var harorat float64 = 36.6
var masofa float32 = 12.5
Tur O'lchami Taxminiy aniqligi
float32 32 bit 6–7 ta o'nlik raqam
float64 64 bit 15–16 ta o'nlik raqam

Go kasrli sonlarni odatda float64 deb aniqlaydi. Shu sababli umumiy hisob-kitoblarda float64 ko'proq ishlatiladi.

main.go
package main

import "fmt"

func main() {
    narx := 12.5
    miqdor := 3.0
    jami := narx * miqdor

    fmt.Printf("Jami: %.2f\n", jami)
}

Natija:

Jami: 37.50

%.2f kasrli sonni verguldan keyin ikki xona bilan chiqaradi.

Info

float32 va float64 ayrim o'nli kasrlarni aniq saqlay olmaydi. Pulli hisob kittoblarda yaxlitlash xatosi bo'lmasligi uchun butun son sifatida saqlash to'g'ri bo'ladi. Masalan, 1250 tiyin — 12.50 so'm.

Mantiqiy tur: bool

bool faqat ikki qiymatdan birini saqlaydi: true yoki false. U ha yoki yo'q ko'rinishidagi holatlar uchun ishlatiladi:

var faol bool = true
var bloklangan bool = false

Taqqoslash natijasi ham bool bo'ladi:

main.go
package main

import "fmt"

func main() {
    yosh := 20
    voyagaYetgan := yosh >= 18

    fmt.Println("Voyaga yetganmi?", voyagaYetgan)
}

Natija:

Voyaga yetganmi?: true

Keyingi qismlarda bool qiymatlarni if shartlarida ishlatamiz.

Matn turi: string

string matnni, ya'ni baytlar ketma-ketligini saqlaydi. Matn qo'shtirnoq ichida yoziladi:

ism := "Dilshod"
xabar := "Goni o'rganamiz"
boshMatn := ""

Ikki matnni + operatori bilan birlashtirish mumkin:

main.go
package main

import "fmt"

func main() {
    ism := "Dilshod"
    xabar := "Salom, " + ism + "!"

    fmt.Println(xabar)
}

Natija:

Salom, Dilshod!

Goda matn UTF-8 kodlashida yoziladi. Shu sababli o'zbekcha harflar va boshqa yozuv tizimlari bilan ishlashda muamo yuzaga kelmaydi.

byte va rune

byteuint8 turining boshqa nomi. U ko'pincha ma'lumotning bitta baytini ifodalash uchun ishlatiladi.

runeint32 turining boshqa nomi. U Unicode uchun, odatda bitta belgini ifodalaydi. Rune bittalik tirnoq ichida yoziladi:

var harf rune = 'O'
var maxsusHarf rune = '''

string uzunligini len() bilan olganda baytlar soni qaytadi. Unicode belgilar soni bundan farq qilishi mumkin:

main.go
package main

import "fmt"

func main() {
    matn := "Go😊"

    fmt.Println("Baytlar:", len(matn))
    fmt.Println("Belgilar:", len([]rune(matn)))
}

Natija:

Baytlar: 6
Belgilar: 3

G va o bittadan bayt, 😊 esa UTF-8 da to'rt bayt egallaydi. []rune(matn) matnni Unicode belgilar ketma-ketligiga aylantiradi. Bu tur haqida keyingi darslarda batafsil tushuntiriladi.

Kompleks sonlar

Go complex64 va complex128 turlarga ham ega. Kompleks son haqiqiy va mavhum qismlardan tashkil topadi:

var z complex128 = complex(2, 3) // 2 + 3i

Bu turlar ilmiy va muhandislik hisoblarida ishlatiladi. Oddiy dasturlarda kam uchraydi, shu sababli hozircha ularni tanib olish yetarli.

Turlarni o'zgartirish

Go son turlarini avtomatik ravishda bir-biriga o'girmaydi. Turlar boshqa bo'lsa, aniq konvertatsiya yozilishi kerak:

main.go
package main

import "fmt"

func main() {
    var dona int = 5
    var narx float64 = 12.5

    jami := float64(dona) * narx
    fmt.Println(jami)
}

float64(dona) dona qiymatini hisob uchun float64 turiga aylantiradi. Asl dona o'zgaruvchisi int ligicha qoladi, faqat hisob kitob vaqtida float64 ga o'zgaradi.

Kasrli sonni butun songa aylantirganda kasr qismi tashlab yuboriladi:

kasr := 9.8
son := int(kasr) // 9

Bu yaxlitlash emas. 9.8 ham, 9.2 ham intga aylantirilganda 9 bo'ladi.

Warning

Katta sonni kichik oraliqli turga aylantirish qiymatni xato qilishi mumkin. Masalan, qiymat := 300 dan keyin uint8(qiymat) natijasi 44 bo'ladi. uint8(300)ga esa kompilyator ruxsat bermaydi. Konvertatsiyadan oldin qiymat yangi tur oralig'iga sig'ishini tekshirish kerak.

Sonni matnga yoki matnni songa aylantirish oddiy tur konvertatsiyasidan farq qiladi. Buning uchun odatda strconv paketi ishlatiladi. Bu mavzuni ma'lumot kiritish va paketlar bilan ishlashda ko'ramiz.

Nol qiymatlar

Boshlang'ich qiymat berilmagan o'zgaruvchi turiga mos nol qiymat oladi:

Tur Nol qiymat
butun va kasrli sonlar 0
kompleks sonlar 0+0i
bool false
string ""
main.go
package main

import "fmt"

func main() {
    var son int
    var narx float64
    var faol bool
    var xabar string

    fmt.Printf("son=%d, narx=%.1f, faol=%t, xabar=%q\n", son, narx, faol, xabar)
}

Natija:

son=0, narx=0.0, faol=false, xabar=""

Qaysi turni tanlash kerak?

Yangi boshlaganda quyidagi oddiy qoida yetarli:

  • butun son uchun int;
  • kasrli son uchun float64;
  • matn uchun string;
  • ha yoki yo'q holati uchun bool;
  • bitta Unicode belgisi uchun rune;

Array, slice, map, struct, pointer, function, interface va channel ham Godagi turlar. Ular bir nechta qiymatni saqlash yoki murakkab qiymatlarni ifodalash uchun ishlatiladi va keyingi qismlarda alohida ko'rib chiqamiz.

Info

nil alohida tur emas. Ayrim turlarda qiymat mavjud emasligini bildiruvchi maxsus qiymat.

Misollar

1. Butun son turining chegarasi

math paketidagi o‘zgarmaslar tur sig‘imini ko‘rsatadi:

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println(math.MinInt8, math.MaxInt8)
}

int8 turi -128 dan 127 gacha qiymat saqlaydi. Undan katta son uchun kengroq tur tanlanadi.

2. Ishorasiz butun son

Manfiy bo‘la olmaydigan kichik qiymatlar uchun uint8 ishlatilishi mumkin:

package main

import "fmt"

func main() {
    var qizil uint8 = 255
    fmt.Println(qizil)
}

uint8 oralig‘i 0 dan 255 gacha. Manfiy qiymatni bu turga berish kompilyatsiya xatosini chiqaradi.

3. Tur o‘zgartirish

Go son turlarini yashirin ravishda aralashtirmaydi:

package main

import "fmt"

func main() {
    soni := 3
    narx := 12.5
    jami := float64(soni) * narx
    fmt.Println(jami)
}

soni avval float64ga aniq o‘tkazildi. Aks holda int va float64ni ko‘paytirib bo‘lmaydi.

4. Butun songa o‘tkazishda kasr qismi

Kasrli son intga o‘tkazilganda kasr qismi tashlanadi:

package main

import "fmt"

func main() {
    musbat, manfiy := 8.9, -8.9
    fmt.Println(int(musbat), int(manfiy))
}

Natija 8 -8 bo‘ladi. Qiymat yaxlitlanmaydi, nol tomonga qisqartiriladi.

5. byte turida belgi saqlash

byteuint8 turining boshqa nomi:

package main

import "fmt"

func main() {
    var belgi byte = 'G'
    fmt.Printf("%d %c %T\n", belgi, belgi, belgi)
}

Natijada 71 G uint8 chiqadi. byteuint8 turining boshqa nomi va bitta bayt qiymatini saqlaydi.

6. rune bilan Unicode belgi

runeint32 turining boshqa nomi va bitta Unicode kod nuqtasini saqlaydi:

package main

import "fmt"

func main() {
    belgi := '‘'
    fmt.Printf("%c %U %T\n", belgi, belgi, belgi)
}

%c belgining o‘zini, %U Unicode kodini, %T esa uning int32 turini ko‘rsatadi.

7. Ilmiy yozuvdagi kasrli son

Juda katta yoki kichik kasrli sonni ilmiy yozuvda berish mumkin:

package main

import "fmt"

func main() {
    yoruglikTezligi := 3e8
    kichikQiymat := 1.5e-3
    fmt.Println(yoruglikTezligi, kichikQiymat)
}

3e83 × 10⁸, 1.5e-3 esa 1.5 × 10⁻³ degani. Ikkala qiymat ham float64 sifatida aniqlanadi.

8. Xom matn literali

Teskari qo‘shtirnoq ichidagi matnda qator va \ belgisi o‘z holicha saqlanadi:

package main

import "fmt"

func main() {
    yol := `C:\Users\Ali\main.go`
    fmt.Println(yol)
}

Bunday literal fayl yo‘li, ko‘p qatorli matn yoki escape belgilar ko‘p bo‘lgan qiymatlar uchun qulay.

9. Kompleks son

Go kompleks sonlar uchun complex64 va complex128 turlariga ega:

package main

import "fmt"

func main() {
    z := complex(3.0, 4.0)
    fmt.Println(z, real(z), imag(z))
}

complex() haqiqiy va mavhum qismlarni birlashtiradi. real() va imag() ularni qayta ajratadi.

10. Turini format orqali ko‘rish

%T o‘zgaruvchining aniqlangan turini ko‘rsatadi:

package main

import "fmt"

func main() {
    butun := 26
    kasr := 26.5
    matn := "26.5"
    fmt.Printf("%T %T %T\n", butun, kasr, matn)
}

Ko‘rinishi o‘xshash qiymatlar turlicha bo‘lishi mumkin. Natijada int float64 string chiqadi.