Pointers Into Slices
Pointerlar slice ichida
Sizning xizmatingiz kechikish namunalarining to'plamini yozib oldi, lekin xato har bir o'qishga qo'shimcha 20ms qo'shib qo'ygan. Siz o'sha 20ms'ni har bir namunadan qaytadan ayirmoqchisiz, shuning uchun oddiy sikl yozasiz:
samples := []int{120, 145, 98, 200}
for _, s := range samples {
s -= 20
}
fmt.Println(samples) // [120 145 98 200]Slice o'zgarishsiz qoldi.
Nega range sikllari o'zgartirmaydi
range sizga har bir elementning yangi nusxasini beradi. s — samples[0]ning nusxasi, keyin samples[1]ning nusxasi, va h.k. sdan ayirish nusxani o'zgartiradi, keyin navbatdagi o'tish uni tashlab yuboradi. Slice hech qachon o'zgarmadi.
Buning o'rniga slice ichiga indekslang:
for i := range samples {
samples[i] -= 20
}samples[i] to'g'ridan-to'g'ri slicening tub massiviga yozadi. O'zgarish har bir element ustida arifmetika kabi inline qilish uchun yetarlicha oddiy bo'lganda shunga murojaat qiling.
Manzil kerak bo'lganda
Ba'zan boshqa funksiya ishni bajaradi. Aytaylik, metrikalar jamoasi shu yordamchini yetkazadi:
func Calibrate(p *int, offset int) {
*p -= offset
}U *int qabul qiladi, shuning uchun unga elementning manzilini berasiz:
for i := range samples {
Calibrate(&samples[i], offset)
}&samples[i] tub massivdagi i elementiga ishora qiladi. Yordamchi o'sha pointer orqali yozadi, va slice o'zgarishni ko'radi.
Kontentni tahrirlash va slicening o'zini qayta belgilash
Slice qiymati allaqachon o'z tub massiviga havolani olib yuradi, shuning uchun funksiya oddiy []int orqali elementlarni tahrirlashi mumkin. Buning uchun *[]int kerak emas. *[]intga faqat funksiya slice header'ining o'zini qayta belgilaganda, masalan uni append bilan kengaytirganda murojaat qiling.
>_ Exercise
Onlayn do'kon mijoz bitta buyurtmada bitta mahsulotdan qancha sotib olishi mumkinligini cheklaydi. Savatchangiz har bir mahsulot uchun sonini ushlab turadi. Hech qanday son shu buyurtma chegarasidan oshmasligi kerak. Ikkala funksiyani yozing:
Signaturalar
func Limit(qty *int, max int)
func LimitAll(quantities []int, max int)Talablar
- •
Limit*intqabul qiladi va uni faqatmaxdan oshsamaxgacha qisqartiradi - •
LimitAllquantitiesdagi har bir element uchun bir martaLimitni chaqiradi, joyida o'zgartirib, qaytish qiymatisiz
Qochish kerak bo'lgan tuzoq
for _, q := range quantities { Limit(&q, max) } slice elementining emas, sikl o'zgaruvchisining manzilini oladi. Buning o'rniga indeks bo'yicha aylaning.
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
range sizga har bir elementning nusxasini beradi, shuning uchun slicani o'zgartirish uchun uning haqiqiy elementiga samples[i] orqali indeks bilan yetib borasiz.
NEXT UP
Pointer to Struct
$ go run main.go
Kodingizni ishga tushiring