Darsliklar Go Lang Ko'rsatkichlar

Go Lang Go Lang Ko'rsatkichlar

Ko’rsatkich (pointer) — o’zgaruvchining qiymatini emas, uning xotiradagi manzilini saqlaydigan tur. Go’da ko’rsatkichlar C++’dagiga o’xshaydi, lekin muhim farq bilan: Go’da ko’rsatkich arifmetikasi yo’q — manzilga son qo’shib-ayirib bo’lmaydi, bu xavfsizlikni oshiradi.

Ko’rsatkich*Tur shaklida yoziladigan, boshqa o’zgaruvchining manzilini saqlovchi qiymat. & operatori manzilni oladi, * esa o’sha manzildagi qiymatga murojaat qiladi (dereference).

Manzil olish va dereference

package main

import "fmt"

func main() {
    son := 42
    korsatkich := &son

    fmt.Println(son)
    fmt.Println(*korsatkich)

    *korsatkich = 100
    fmt.Println(son)
}
42
42
100

&sonsonning xotiradagi manzilini oldi, korsatkich shu manzilni saqlaydi. *korsatkich — o’sha manzildagi qiymatni o’qiydi (42). *korsatkich = 100 esa manzil orqali asl sonning o’zini o’zgartirdi — shuning uchun keyingi sonni chop etish 100 berdi.

Ko’rsatkichni chop etish — manzilning o’zi

Agar ko’rsatkichning o’zini (dereference qilmasdan) chop etsangiz, u xotiradagi manzilni ko’rsatadi:

package main

import "fmt"

func main() {
    son := 42
    korsatkich := &son
    fmt.Println(korsatkich)
}
0xc00011a010

Bu — son joylashgan xotira manzili (har safar ishga tushirilganda boshqacha bo’lishi mumkin). Amaliyotda ko’rsatkichning o’zini chop etish kamdan-kam foydali — odatda *korsatkich orqali qiymatning o’zi kerak bo’ladi.

nil ko’rsatkich

Hech qanday manzilga ishora qilmagan ko’rsatkichning zero value’si — nil. Uni dereference qilishga urinish dasturni qulatadi:

package main

import "fmt"

func main() {
    var p *int
    fmt.Println(*p)
}
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x...]

goroutine 1 [running]:
main.main()
    ...
exit status 2

var p *intpga hech qanday manzil berilmadi, u nil. *p esa mavjud bo’lmagan manzildagi qiymatni o’qishga urindi — bu ijro vaqtidagi jiddiy xato (panic). Ko’rsatkich bilan ishlashdan oldin uning nil emasligini tekshirish yaxshi amaliyot hisoblanadi.

Struct’ga ko’rsatkich — avtomatik dereference

Struct’ga ko’rsatkich orqali maydonga murojaat qilinganda, Go C++’dagi -> o’rniga oddiy nuqtani ishlatishga ruxsat beradi:

package main

import "fmt"

type Foydalanuvchi struct {
    Ism string
}

func main() {
    u := Foydalanuvchi{Ism: "Farrux"}
    p := &u

    p.Ism = "Master Sherkulov"

    fmt.Println(u.Ism)
}
Master Sherkulov

p.Ism — to’liq yozilsa (*p).Ism bo’lishi kerak edi, lekin Go buni avtomatik bajaradi. p.Ism = "..." orqali qilingan o’zgarish asl uda ham ko’rindi, chunki p uning aynan o’ziga ishora qiladi. Bu naqsh keyingi darsda struct metodlarini o’rganishda markaziy ahamiyat kasb etadi.