GoDasturchi
Value vs Pointer Receivers

Value vs Pointer Receivers

Value va pointer receiverlar

Ikkala metod ham Hitsni bir xil kod qatori bilan oshiradi. Ular bir xil natija bermaydi.

example.go
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 — 1

Receiver — 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'radiStructning nusxasiAsl nusxa, uning manzili orqali
Chaqiruvchiga o'zgarish ko'rinadimiYo'qHa
Katta structda har bir chaqiruv narxiHar bir maydonni nusxalaydiBitta 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:

example.go
Cache{}.hitPointer() // kompilyatsiya xatosi: Cache{}ning manzilini olib bo'lmaydi

Avval uni o'zgaruvchiga saqlang, keyin metodni chaqiring:

example.go
c := Cache{}
c.hitPointer() // yaxshi, c manzilga ega

Faqat 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): yana n bayt kelganini qayd eting
  • Done() bool: Received Totalga yetganini xabar qiling

Talablar

  • Har bir Advancedan kelgan baytlar chaqiruvlar bo'ylab yig'ilishi kerak, shuning uchun Advancega pointer receiver kerak
  • Received Totalga yetgach Done true qaytaradi
  • Done faqat o'qiydi, shuning uchun ikkala receiver ham kompilyatsiya bo'ladi. Unga ham pointer bering, shunda Downloadning har bir metodi bir xil e'lon qilinadi

Stuck? Reveal a hint to help you.

Hints (0/4)

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

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

Value vs Pointer Receivers

Value va pointer receiverlar

Ikkala metod ham Hitsni bir xil kod qatori bilan oshiradi. Ular bir xil natija bermaydi.

example.go
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 — 1

Receiver — 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'radiStructning nusxasiAsl nusxa, uning manzili orqali
Chaqiruvchiga o'zgarish ko'rinadimiYo'qHa
Katta structda har bir chaqiruv narxiHar bir maydonni nusxalaydiBitta 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:

example.go
Cache{}.hitPointer() // kompilyatsiya xatosi: Cache{}ning manzilini olib bo'lmaydi

Avval uni o'zgaruvchiga saqlang, keyin metodni chaqiring:

example.go
c := Cache{}
c.hitPointer() // yaxshi, c manzilga ega

Faqat 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): yana n bayt kelganini qayd eting
  • Done() bool: Received Totalga yetganini xabar qiling

Talablar

  • Har bir Advancedan kelgan baytlar chaqiruvlar bo'ylab yig'ilishi kerak, shuning uchun Advancega pointer receiver kerak
  • Received Totalga yetgach Done true qaytaradi
  • Done faqat o'qiydi, shuning uchun ikkala receiver ham kompilyatsiya bo'ladi. Unga ham pointer bering, shunda Downloadning har bir metodi bir xil e'lon qilinadi

Stuck? Reveal a hint to help you.

Hints (0/4)

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