Value vs Pointer Receivers
Value va pointer receiverlar
Ikkala metod ham Hitsni bir xil kod qatori bilan oshiradi. Ular bir xil natija bermaydi.
type Cache struct{ Hits int }
func (c Cache) hitValue() { c.Hits++ }
func (c *Cache) hitPointer() { c.Hits++ }
users := Cache{}
sessions := Cache{}
users.hitValue()
sessions.hitPointer()
// users.Hits — 0, sessions.Hits — 1Receiver — bu shunchaki metod nomi oldida turgan parametr, shuning uchun u istalgan argument kabi bir xil qoidalarga amal qiladi. (c Cache) bilan, Go structni cga nusxalaydi; c.Hits++ nusxani oshiradi va metod qaytganda o'zgarish yo'qoladi. (c *Cache) bilan, Go faqat manzilni nusxalaydi, shuning uchun c.Hits++ aslga yozadi.
Yonma-yon
| (c Cache) | (c *Cache) | |
|---|---|---|
| Metod nimani ko'radi | Structning nusxasi | Asl nusxa, uning manzili orqali |
| Chaqiruvchiga o'zgarish ko'rinadimi | Yo'q | Ha |
| Katta structda har bir chaqiruv narxi | Har bir maydonni nusxalaydi | Bitta pointerni nusxalaydi |
Avtomatik manzillashning chegarasi bor
sessions.hitPointer() ishlaydi, garchi sessions *Cache emas, Cache bo'lsa ham. Go chaqiruvni siz uchun (&sessions).hitPointer() deb qayta yozadi. Bu qisqartma faqat olinadigan manzil bo'lganda ishlaydi. Nomlangan o'zgaruvchida u bor; inline yozilgan struct literalida esa yo'q:
Cache{}.hitPointer() // kompilyatsiya xatosi: Cache{}ning manzilini olib bo'lmaydiAvval uni o'zgaruvchiga saqlang, keyin metodni chaqiring:
c := Cache{}
c.hitPointer() // yaxshi, c manzilga egaFaqat o'zgartiradiganlarga pointer kerak
Faqat receiverini o'qiydigan metod value bilan yaxshi kompilyatsiya bo'ladi. Turdagi biror metodga pointer kerak bo'lgan zahoti, andaza — ularning barchasiga pointer berish.
>_ Exercise
Download faylning nechta bayti kelganini kuzatadi. Advance value receiver bilan yetkaziladi, shuning uchun bayt soni hech qachon o'zgarmaydi. Tanalarni amalga oshiring va progress to'planishi uchun receiverlarni tuzating.
Metodlar
- •
Advance(n int): yananbayt kelganini qayd eting - •
Done() bool:ReceivedTotalga yetganini xabar qiling
Talablar
- •Har bir
Advancedan kelgan baytlar chaqiruvlar bo'ylab yig'ilishi kerak, shuning uchunAdvancega pointer receiver kerak - •
ReceivedTotalga yetgachDonetrueqaytaradi - •
Donefaqat o'qiydi, shuning uchun ikkala receiver ham kompilyatsiya bo'ladi. Unga ham pointer bering, shundaDownloadning har bir metodi bir xil e'lon qilinadi
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Value receiverlar nusxani ko'radi va o'zgartira olmaydi. Pointer receiverlar aslini ko'radi va o'zgartira oladi. Turdagi bitta metodga pointer kerak bo'lgan zahoti, ularning barchasiga bering.
NEXT UP
When to Use a Pointer
$ go run main.go
Kodingizni ishga tushiring