11-bo‘lim

Strukturalar

type bilan o'z turini yaratish, maydonlar, literal shakllari, ichma-ich va joylashtirilgan strukturalar, taqqoslash va struktura teglari.

🕑 13 daqiqa o‘qish 📄 650 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. E'lon qilish
  2. Yaratishning shakllari
  3. Ko'rsatkich orqali
  4. Ichma-ich strukturalar
  5. Joylashtirish
  6. Taqqoslash
  7. Strukturalar slicesi
  8. Strukturani o'zgartirish
  9. Anonim struktura
  10. Struktura teglari
  11. Xulosa

Struktura - bir nechta maydonni bitta nom ostida birlashtiradigan tur. Go da sinf yo'q, shuning uchun struktura ma'lumotni tashkil qilishning asosiy vositasi.

E'lon qilish #

Go
package main

import "fmt"

type Talaba struct {
    Ism    string
    Yosh   int
    Shahar string
}

func main() {
    var t Talaba
    fmt.Println(t)
    fmt.Printf("%+v\n", t)

    t.Ism = "Malika"
    t.Yosh = 20
    fmt.Printf("%+v\n", t)
}
Natija
{ 0 }
{Ism: Yosh:0 Shahar:}
{Ism:Malika Yosh:20 Shahar:}

E'lon qilingan struktura darhol ishlatishga tayyor: har bir maydon o'z nol qiymatini oladi.

%+v - maydon nomlari bilan birga chiqaradi. Nosozlikni izlashda juda foydali.

Yaratishning shakllari #

Go
package main

import "fmt"

type Talaba struct {
    Ism    string
    Yosh   int
    Shahar string
}

func main() {
    a := Talaba{Ism: "Husanboy", Yosh: 25, Shahar: "Namangan"}
    b := Talaba{"Nodira", 22, "Andijon"}
    c := Talaba{Ism: "Aziza"}

    fmt.Printf("%+v\n", a)
    fmt.Printf("%+v\n", b)
    fmt.Printf("%+v\n", c)
}
Natija
{Ism:Husanboy Yosh:25 Shahar:Namangan}
{Ism:Nodira Yosh:22 Shahar:Andijon}
{Ism:Aziza Yosh:0 Shahar:}
Tartib bo'yicha yozishdan saqlaning

Talaba{"Nodira", 22, "Andijon"} - qisqa, lekin mo'rt.

Agar kelajakda strukturaga yangi maydon qo'shsangiz yoki maydonlar tartibini o'zgartirsangiz, bu kod jimgina noto'g'ri ishlaydi yoki kompilyatsiya bo'lmaydi.

Maydon nomlari bilan yozilgan shakl esa o'zgarishlarga bardosh beradi va o'qiganda nima nima ekani darhol ko'rinadi.

Qoida: har doim Ism: "Nodira" shaklini ishlating.

Ko'rsatkich orqali #

Go
package main

import "fmt"

type Talaba struct {
    Ism  string
    Ball int
}

func main() {
    t := &Talaba{Ism: "Kamola", Ball: 90}

    t.Ball = 95
    fmt.Println(t.Ism, t.Ball)
    fmt.Printf("%+v\n", *t)

    fmt.Println(t)
}
Natija
Kamola 95
{Ism:Kamola Ball:95}
&{Kamola 95}

&Talaba{...} - strukturani yaratib, darhol uning manzilini beradi.

Nuqta orqali murojaat ikkala holatda ham bir xil ishlaydi - Go farqini o'zi hal qiladi (8-bo'lim).

fmt.Println(t) ko'rsatkich uchun & belgisi bilan chiqaradi.

Ichma-ich strukturalar #

Go
package main

import "fmt"

type Manzil struct {
    Shahar string
    Kocha  string
}

type Talaba struct {
    Ism    string
    Manzil Manzil
}

func main() {
    t := Talaba{
        Ism: "Dilnoza",
        Manzil: Manzil{
            Shahar: "Namangan",
            Kocha:  "Navoiy",
        },
    }

    fmt.Println(t.Manzil.Shahar)
    fmt.Printf("%+v\n", t)
}
Natija
Namangan
{Ism:Dilnoza Manzil:{Shahar:Namangan Kocha:Navoiy}}

Struktura ichida boshqa struktura bo'lishi mumkin. Murojaat nuqta orqali zanjir bo'lib ketadi: t.Manzil.Shahar.

Joylashtirish #

Go
package main

import "fmt"

type Manzil struct {
    Shahar string
    Kocha  string
}

type Talaba struct {
    Ism string
    Manzil
}

func main() {
    t := Talaba{
        Ism:    "Husanboy",
        Manzil: Manzil{Shahar: "Namangan", Kocha: "Navoiy"},
    }

    fmt.Println(t.Shahar)
    fmt.Println(t.Manzil.Shahar)
}
Natija
Namangan
Namangan

Maydonga nom bermasdan, faqat turni yozsangiz, u joylashtirilgan (embedded) bo'ladi.

Shunda ichki maydonlarga to'g'ridan-to'g'ri murojaat qilish mumkin: t.Shahar, t.Manzil.Shahar emas.

Joylashtirish - Go dagi vorislik o'rnini bosuvchi

Java da class Talaba extends Shaxs deb yozilardi. Go da vorislik yo'q, uning o'rniga joylashtirish bor.

Farqi muhim: vorislikda "Talaba bu Shaxs" degan munosabat o'rnatiladi. Joylashtirishda esa "Talaba ichida Manzil bor" - bu ancha sodda va moslashuvchan.

Joylashtirilgan turning metodlari ham tashqariga chiqadi - buni keyingi bo'limda ko'ramiz.

Go jamoasining qoidasi: birlashtirish vorislikdan afzal.

Taqqoslash #

Go
package main

import "fmt"

type Nuqta struct {
    X, Y int
}

func main() {
    a := Nuqta{1, 2}
    b := Nuqta{1, 2}
    c := Nuqta{3, 4}

    fmt.Println(a == b)
    fmt.Println(a == c)

    joylar := map[Nuqta]string{
        {0, 0}: "markaz",
        {1, 2}: "birinchi",
    }
    fmt.Println(joylar[a])
}
Natija
true
false
birinchi

Strukturalarni == bilan taqqoslash mumkin - u hamma maydonni solishtiradi.

Taqqoslanadigan struktura map da kalit ham bo'la oladi.

Hamma struktura taqqoslanmaydi

Agar strukturada slice, map yoki funksiya maydoni bo'lsa, uni == bilan taqqoslab bo'lmaydi - bu kompilyatsiya xatosi:

Go
type Guruh struct {
    Nom      string
    Talabalar []string   // slice
}
// a == b  ->  invalid operation: struct containing []string
// cannot be compared

Sabab: slice ning nimasini solishtirish kerak - manzilinimi yoki mazmuninimi? Go bu savolga javob taxmin qilmaydi.

Bunday strukturalar uchun reflect.DeepEqual yoki o'z taqqoslash funksiyangizni yozasiz.

Strukturalar slicesi #

Go
package main

import (
    "fmt"
    "slices"
)

type Talaba struct {
    Ism  string
    Ball int
}

func main() {
    guruh := []Talaba{
        {Ism: "Malika", Ball: 88},
        {Ism: "Husanboy", Ball: 92},
        {Ism: "Aziza", Ball: 79},
    }

    slices.SortFunc(guruh, func(a, b Talaba) int {
        return b.Ball - a.Ball
    })

    for _, t := range guruh {
        fmt.Printf("%-10s %d\n", t.Ism, t.Ball)
    }
}
Natija
Husanboy   92
Malika     88
Aziza      79

Slice ichida struktura turini yozgach, har bir element uchun turni takrorlash shart emas: {Ism: "Malika", Ball: 88} yetarli.

slices.SortFunc taqqoslash funksiyasini oladi. U manfiy, nol yoki musbat son qaytarishi kerak - bu yerda b.Ball - a.Ball kamayish tartibini beradi.

Strukturani o'zgartirish #

Go
package main

import "fmt"

type Talaba struct {
    Ism  string
    Ball int
}

func main() {
    guruh := []Talaba{
        {Ism: "Malika", Ball: 88},
        {Ism: "Aziza", Ball: 79},
    }

    for _, t := range guruh {
        t.Ball += 5
    }
    fmt.Println(guruh[0].Ball)

    for i := range guruh {
        guruh[i].Ball += 5
    }
    fmt.Println(guruh[0].Ball)
}
Natija
88
93

Birinchi sikl hech narsani o'zgartirmadi - range strukturaning nusxasini beradi (6-bo'lim).

O'zgartirish uchun indeks orqali murojaat qilish kerak.

Anonim struktura #

Go
package main

import "fmt"

func main() {
    sozlama := struct {
        Port  int
        Nosoz bool
    }{
        Port:  8080,
        Nosoz: true,
    }

    fmt.Printf("%+v\n", sozlama)
    fmt.Println(sozlama.Port)
}
Natija
{Port:8080 Nosoz:true}
8080

Tur nomi kerak bo'lmaganda, strukturani joyida e'lon qilish mumkin.

Bu ko'pincha testlarda va bir martalik sozlamalarda ishlatiladi.

Struktura teglari #

Go
package main

import (
    "encoding/json"
    "fmt"
)

type Talaba struct {
    Ism    string `json:"ism"`
    Ball   int    `json:"ball"`
    Maxfiy string `json:"-"`
}

func main() {
    t := Talaba{Ism: "Nodira", Ball: 91, Maxfiy: "ko'rinmaydi"}

    chiqish, xato := json.Marshal(t)
    if xato != nil {
        fmt.Println("xato:", xato)
        return
    }
    fmt.Println(string(chiqish))

    var qayta Talaba
    json.Unmarshal([]byte(`{"ism":"Aziza","ball":80}`), &qayta)
    fmt.Printf("%+v\n", qayta)
}
Natija
{"ism":"Nodira","ball":91}
{Ism:Aziza Ball:80 Maxfiy:}

Maydondan keyingi teskari qo'shtirnoq ichidagi matn - teg. U kutubxonalarga qo'shimcha ko'rsatma beradi.

json:"ism" - JSON da maydon nomi ism bo'lsin. json:"-" esa maydonni butunlay chiqarib tashlaydi.

Faqat katta harfli maydonlar tashqariga chiqadi

Yuqoridagi misolda Maxfiy maydoni json:"-" tufayli chiqarilmadi. Lekin yana bir qoida bor:

Go da nomi kichik harf bilan boshlanadigan maydon paketdan tashqariga umuman ko'rinmaydi. json paketi ham uni ko'rmaydi va jimgina tashlab ketadi.

Shuning uchun JSON ga chiqadigan maydonlar doim katta harf bilan boshlanishi kerak. Bu qoidani 16-bo'limda batafsil ko'ramiz.

Amaliy topshiriq
  1. Uch maydonli struktura e'lon qilib, nol qiymatlarini chiqaring.
  2. %v va %+v farqini ko'rsating.
  3. Maydon nomlari bilan va tartib bilan yaratishni solishtiring.
  4. &Talaba{...} bilan ko'rsatkich yarating.
  5. Ichma-ich struktura tuzib, zanjir orqali murojaat qiling.
  6. Joylashtirish bilan maydonni to'g'ridan-to'g'ri oling.
  7. Ikki strukturani == bilan taqqoslang.
  8. Slice maydonli strukturani taqqoslashga urinib, xatoni o'qing.
  9. slices.SortFunc bilan strukturalarni saralang.
  10. JSON teglari bilan strukturani chiqarib, qayta o'qing.

Xulosa #

  • type Nom struct { ... } - o'z turingizni yaratadi; maydonlar darhol nol qiymat oladi.
  • Har doim maydon nomlari bilan yarating - tartib bo'yicha yozish mo'rt.
  • &Talaba{...} ko'rsatkich beradi; nuqta ikkala holatda ham ishlaydi.
  • Joylashtirish (nomsiz maydon) ichki maydonlarni tashqariga chiqaradi - bu Go da vorislik o'rnini bosadi.
  • Strukturalarni == bilan taqqoslash mumkin, lekin ichida slice, map yoki funksiya bo'lsa - mumkin emas.
  • range strukturaning nusxasini beradi; o'zgartirish uchun indeks ishlating.
  • Teglar kutubxonalarga ko'rsatma beradi, masalan json:"ism".
  • Tashqariga faqat katta harfli maydonlar ko'rinadi.

Keyingi bo'limda metodlarni o'rganamiz.

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.