The new Builtin
Yangi `new` o'rnatilgan funksiyasi
Konfiguratsiya struct'i ko'pincha ikkita holatni farqlashi kerak: chaqiruvchi ataylab nolga o'rnatgan maydon, va u umuman o'rnatmagan maydon. Oddiy int buni qila olmaydi, chunki 0 ikkalasini ham anglatishi mumkin. Pointer esa qila oladi: nil — "o'rnatilmagan", boshqa istalgan qiymat — haqiqiy tanlov.
type RetryConfig struct {
MaxAttempts *int // nil "standartdan foydalanish"ni bildiradi, "nol urinish" emas
Backoff *bool // nil "o'rnatilmagan"ni bildiradi, "false" emas
}Shunday qilib, MaxAttemptsni standart bo'yicha 5ga o'rnatish uchun, sizga 5ga ishora qiluvchi *int kerak. Ochiq-oydin yechim kompilyatsiya bo'lmaydi:
cfg.MaxAttempts = &5 // kompilyatsiya xatosi: 5ning manzilini olib bo'lmaydi& o'zgaruvchining manzilini oladi, 5 esa o'zgaruvchi emas, literal. Xo'sh, literalga pointerni qanday olasiz?
Eski yechim
Eski kod literalni bitta qatorli yordamchiga o'raydi, shunda unga ishora qiladigan o'zgaruvchi paydo bo'ladi:
func intPtr(v int) *int { return &v }
cfg.MaxAttempts = intPtr(5)Literal v parametriga aylanadi, bu o'zgaruvchi, shuning uchun &v to'g'ri. Shuning uchun intPtr, strPtr, va boolPtr shunchalik ko'p loyihalarda uchraydi.
Go 1.26 usuli
Go 1.26 newga faqat tur emas, ifodani ham qabul qilish imkonini beradi. U joy ajratadi, qiymatni saqlaydi va pointerni qaytaradi:
cfg.MaxAttempts = new(5) // 5ga ishora qiluvchi *int, yordamchisiz
fmt.Println(*cfg.MaxAttempts) // 5Bundan buyon newga murojaat qiling. O'sha intPtr yordamchilari faqat til keyinchalik yopgan bo'shliqni chetlab o'tish uchun mavjud edi.
>_ Exercise
Configda pointer maydonlari bor, shuning uchun nil "chaqiruvchi buni hech qachon o'rnatmagan"ni bildiradi, va nolmas har qanday qiymat — ataylab qilingan tanlov. U yaratadigan Server esa oddiy qiymatlarni ushlab turadi, chunki server yaratilgandan keyin har bir sozlama ma'lum bo'ladi. newServerni tugating, u o'rnatilmagan Config maydonlarini standart qiymatga o'rnatsin, so'ng hal qilingan qiymatlarni ushlab turuvchi *Server qaytarsin.
Config maydonlari pointer, Server maydonlari esa oddiy qiymat bo'lgani uchun, ularni ko'chirayotganda har birini dereferentsiya qiling: *cfg.Port — pointer ishora qilayotgan int.
Talablar
- •Agar
Portnilbo'lsa, uni8080ga standart qiling - •Agar
EnableTLSnilbo'lsa, unitruega standart qiling - •Chaqiruvchi allaqachon o'rnatgan har qanday maydonni o'zgarishsiz qoldiring
- •Har bir standart literalga ishora qilish uchun
new()dan foydalaning, yordamchi funksiyalarsiz - •Serverning
Addrini uning tinglash manziliga,"localhost:<port>", hal qilingan portdan foydalanib o'rnating (fmt.Sprintf("localhost:%d", port)ishlaydi;%dint'ni formatlaydi) - •
Port,EnableTLS, vaAddri hal qilingan qiymatlarni ushlab turadigan*Serverqaytaring
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
new(expr) bitta qadamda qiymat ajratadi va unga pointer qaytaradi, shuning uchun *T maydoni intPtr-uslubidagi yordamchi o'rniga to'g'ridan-to'g'ri literalni olishi mumkin.
NEXT UP
Value vs Pointer Receivers
$ go run main.go
Kodingizni ishga tushiring