11-bo‘lim
Strukturalar
type bilan o'z turini yaratish, maydonlar, literal shakllari, ichma-ich va joylashtirilgan strukturalar, taqqoslash va struktura teglari.
Ushbu bo‘lim mundarijasi
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 #
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)
}
{ 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 #
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)
}
{Ism:Husanboy Yosh:25 Shahar:Namangan}
{Ism:Nodira Yosh:22 Shahar:Andijon}
{Ism:Aziza Yosh:0 Shahar:}
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 #
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)
}
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 #
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)
}
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 #
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)
}
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.
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 #
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])
}
true
false
birinchi
Strukturalarni == bilan taqqoslash mumkin - u hamma maydonni
solishtiradi.
Taqqoslanadigan struktura map da kalit ham bo'la oladi.
Agar strukturada slice, map yoki funksiya maydoni bo'lsa, uni
== bilan taqqoslab bo'lmaydi - bu kompilyatsiya xatosi:
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 #
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)
}
}
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 #
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)
}
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 #
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)
}
{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 #
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)
}
{"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.
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.
- Uch maydonli struktura e'lon qilib, nol qiymatlarini chiqaring.
%vva%+vfarqini ko'rsating.- Maydon nomlari bilan va tartib bilan yaratishni solishtiring.
&Talaba{...}bilan ko'rsatkich yarating.- Ichma-ich struktura tuzib, zanjir orqali murojaat qiling.
- Joylashtirish bilan maydonni to'g'ridan-to'g'ri oling.
- Ikki strukturani
==bilan taqqoslang. - Slice maydonli strukturani taqqoslashga urinib, xatoni o'qing.
slices.SortFuncbilan strukturalarni saralang.- 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 ichidaslice,mapyoki funksiya bo'lsa - mumkin emas. rangestrukturaning 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.
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.