Go’da struct
struct bir-biriga bog‘liq, turli turdagi qiymatlarni bitta yangi turga birlashtiradi. Masalan, mahsulot nomi string, narxi int64, ombordagi holati esa bool bo‘lishi mumkin. Ularni alohida o‘zgaruvchilarda emas, bitta Product qiymatida saqlash kodni aniq qiladi.
Tur yaratish va qiymat berish
package main
import "fmt"
type User struct {
Name string
Age int
Email string
}
func main() {
user := User{
Name: "Ali",
Age: 25,
Email: "[email protected]",
}
fmt.Println(user.Name, user.Age, user.Email)
}
Natija:
Ali 25 [email protected]
type User struct yangi nomlangan tur yaratadi. Name, Age va Email uning maydonlari. Paket tashqarisidan ishlatilishi kerak bo‘lgan tur va maydon nomlari bosh harf bilan boshlanadi.
Nomlangan maydonli literal tartibga bog‘liq emas va yangi maydon qo‘shilganda xavfsizroq. User{"Ali", 25, "[email protected]"} yozish mumkin, ammo maydon tartibi o‘zgarsa kod buziladi; shu sabab amaliy kodda nomlangan ko‘rinish afzal.
Nol qiymat
structning nol qiymatida har bir maydon o‘z turining nol qiymatini oladi:
package main
import "fmt"
type Product struct {
Name string
Price int64
Stock int
}
func main() {
var product Product
fmt.Printf("%q %d %d\n", product.Name, product.Price, product.Stock)
}
Natija:
Yaxshi loyihalangan tur imkon qadar nol qiymatda ham foydali bo‘ladi. Agar ayrim maydonlar majburiy yoki ma’lum oraliqda bo‘lishi kerak bo‘lsa, konstruktor vazifasidagi funksiya va validatsiya ishlatiladi.
Ichma-ich struct
package main
import "fmt"
type Address struct {
City string
Street string
}
type Customer struct {
Name string
Address Address
}
func main() {
customer := Customer{
Name: "Lola",
Address: Address{
City: "Toshkent",
Street: "Amir Temur",
},
}
fmt.Println(customer.Name, customer.Address.City)
}
Natija:
Bu kompozitsiya: Customer ichida aniq nomlangan Address maydoni bor. Go’da klassik meros olish yo‘q; murakkab turlar odatda kichik turlarni birlashtirish orqali quriladi.
Embedding
Maydon nomisiz tur yozilsa, u joylashtirilgan maydon (embedded field) bo‘ladi:
package main
import "fmt"
type Audit struct {
CreatedBy string
}
type Order struct {
ID int
Audit
}
func main() {
order := Order{ID: 42, Audit: Audit{CreatedBy: "admin"}}
fmt.Println(order.ID, order.CreatedBy)
}
Natija:
order.CreatedBy — order.Audit.CreatedByning qisqa ko‘rinishi. Embedding meros olish emas: Order va Audit alohida turlar bo‘lib qoladi. Nomlar to‘qnashsa, to‘liq yo‘l bilan murojaat qilish kerak.
Qiymat semantikasi, pointer va taqqoslash
struct boshqa o‘zgaruvchiga berilganda maydonlari nusxalanadi. Nusxa ichidagi slice, map yoki pointer esa o‘sha asosiy ma’lumotga murojaat qilishi mumkin; bu chuqur nusxa emas. Asl structni o‘zgartirish kerak bo‘lsa, pointer ishlatiladi.
Barcha maydonlari taqqoslanadigan struct == bilan taqqoslanadi. Slice, map yoki funksiya maydoni bor struct to‘g‘ridan-to‘g‘ri taqqoslanmaydi.
Bo‘sh struct
struct{} maydonsiz tur. U odatda qiymatning o‘zi kerak bo‘lmagan to‘plamlarda ishlatiladi:
package main
import "fmt"
func main() {
tags := map[string]struct{}{}
tags["go"] = struct{}{}
_, bor := tags["go"]
fmt.Println(bor)
}
Natija:
Struct xotirada maydonlar tekislanishi (alignment) sabab maydonlar o‘lchamlari yig‘indisidan ko‘proq joy egallashi mumkin. unsafe.Sizeof bilan o‘lchash mumkin, ammo maydonlarni faqat taxmin bilan qayta tartiblashdan oldin profiler va real talabga qarang.
Xulosa
structbog‘liq qiymatlarni yangi nomlangan turga birlashtiradi.- Nomlangan literal maydon tartibiga bog‘liq emas.
- Nol qiymat har bir maydonning nol qiymatlaridan tuziladi.
- Embedding qulay murojaat va metod promotion beradi, ammo meros olish emas.
- Tayinlash sayoz nusxa yaratadi.
Keyingi darsda nomlangan turga xatti-harakat qo‘shadigan metodlar o‘rganiladi.