Skip to Content
Go Realm v1 is released 🎉
TopicsReceiver Function

Golang রিসিভার ফাংশন

Go-তে কোনো type-এর সাথে ফাংশন attach করার উপায়ই হলো Receiver Function। এটি OOP-এর method-এর সমতুল্য — কিন্তু class ছাড়াই।

🚗 অ্যানালজি: একটি গাড়ির নিজস্ব Start(), Stop(), Refuel() আছে। Go-তে Car struct-এর সাথে এই ফাংশনগুলো attach করাই হলো Receiver Function।

১. সাধারণ Function vs Receiver Function

প্রথমে বুঝুন কেন Receiver Function দরকার:

type Car struct { Brand string Speed int } // ❌ সাধারণ Function — Car-এর সাথে কোনো সম্পর্ক নেই func StartCar(c Car) { fmt.Println(c.Brand, "started") } // ✅ Receiver Function — Car-এরই নিজস্ব method func (c Car) Start() { fmt.Println(c.Brand, "started") } // ব্যবহার car := Car{Brand: "Toyota", Speed: 0} StartCar(car) // সাধারণ function call car.Start() // receiver function call — অনেক বেশি readable!

কেন ভালো? Receiver function ব্যবহার করলে code অনেক বেশি organized এবং readable হয়। car.Start() দেখেই বোঝা যায় এটি Car-এর কাজ।


২. Syntax 📌

Receiver function-এর প্রতিটি অংশ:

// ↓ receiver ↓ type ↓ method name ↓ return func (u User) Greet() string { return "Hello, " + u.Name // u দিয়ে struct-এর field access করা যায় }
type User struct { Name string Age int } func (u User) Greet() string { // Value Receiver — read only return "Hello, " + u.Name } func (u *User) Birthday() { // Pointer Receiver — mutates original u.Age++ } func main() { u := User{Name: "Rahim", Age: 25} fmt.Println(u.Greet()) // "Hello, Rahim" u.Birthday() fmt.Println(u.Age) // 26 }

৩. Value vs Pointer Receiver 🔥

📄 সহজ অ্যানালজি:

  • Value Receiver = ফটোকপি নিয়ে কাজ করা। আসল কাগজে কিছু লেখা হয় না।
  • Pointer Receiver = আসল কাগজ নিয়ে কাজ করা। যা লিখবেন তা থেকে যাবে।
বৈশিষ্ট্যValue Receiver (u User)Pointer Receiver (u *User)
আসল struct পরিবর্তন করে?❌ কপিতে কাজ করে✅ original-এ কাজ করে
মেমোরি ব্যবহারপুরো struct copyমাত্র ৪/৮ বাইট (pointer)
ব্যবহারRead-only operationMutating operation
nil safetyসবসময় safenil হলে panic হতে পারে
Interface satisfy করেশুধু T-এর method setT এবং *T উভয়ের method set
func (u User) GetAge() int { return u.Age } // Value — safe copy func (u *User) SetAge(a int) { u.Age = a } // Pointer — modifies original

৪. কোনটা কখন ব্যবহার করবেন? (Production Rule) 🔥

Pointer Receiver ব্যবহার করুন —

  • struct-এর field পরিবর্তন করতে হলে
  • struct বড় হলে (copy cost এড়াতে)
  • sync.Mutex বা অন্য non-copyable field থাকলে
  • consistency রাখতে (একটি struct-এ বেশিরভাগ method pointer হলে বাকিগুলোও pointer রাখুন)

Value Receiver ব্যবহার করুন —

  • শুধু data read করলে
  • struct ছোট এবং immutable হলে (যেমন time.Time)
  • primitive type alias-এ (যেমন type Celsius float64)

⚠️ Golden Rule: একটি struct-এ সব method হয় সবই Value অথবা সবই Pointer receiver রাখুন। Mixed করলে interface satisfaction জটিল হয়।


৫. Method Set ও Interface Satisfaction (Interview Critical) 🔥

🔰 Beginner Note: এই section-টি একটু advanced। প্রথমে §৩ ও §৪ ভালো করে বুঝুন, তারপর এখানে আসুন।

Go-তে কোন receiver type কোন interface satisfy করতে পারে তা নির্ভর করে method set-এর উপর।

সহজ নিয়ম: *T (pointer) সব method call করতে পারে। কিন্তু T (value) শুধু value receiver method-ই call করতে পারে।

TypeMethod Set
T (value)শুধু Value Receiver methods
*T (pointer)Value Receiver + Pointer Receiver — উভয়ই
type Stringer interface { String() string } type Point struct{ X, Y int } func (p *Point) String() string { // Pointer receiver দিয়ে define return fmt.Sprintf("(%d, %d)", p.X, p.Y) } var _ Stringer = &Point{} // ✅ *Point satisfies Stringer var _ Stringer = Point{} // ❌ compile error — Point does NOT satisfy Stringer

কেন? Point (value)-কে সবসময় address করা যায় না (map value, interface value), তাই Go নিরাপত্তার জন্য value type-এ pointer receiver allow করে না।


৬. Receiver Naming Convention

TypeReceiver Name
Useru
Servers
Databasedb
Clientc
Requestr
  • সর্বদা ১-২ অক্ষর, type-এর abbreviation
  • self বা this — Go-তে anti-pattern, ব্যবহার করবেন না
  • একটি struct-এ সব receiver-এর নাম একই রাখুন

৭. Production Patterns

Nil Receiver Handling

type Logger struct{ prefix string } func (l *Logger) Log(msg string) { if l == nil { // nil check — production must fmt.Println("[default]", msg) return } fmt.Println("["+l.prefix+"]", msg) } var l *Logger l.Log("server started") // ✅ panic নেই — "default" print হবে

Method Chaining — Builder Pattern

type QueryBuilder struct { table string limit int offset int } func (q *QueryBuilder) Table(t string) *QueryBuilder { q.table = t; return q } func (q *QueryBuilder) Limit(n int) *QueryBuilder { q.limit = n; return q } func (q *QueryBuilder) Offset(n int) *QueryBuilder { q.offset = n; return q } // Usage q := (&QueryBuilder{}).Table("users").Limit(10).Offset(0)

fmt.Stringer — সবচেয়ে বেশি ব্যবহৃত Interface

type Status int const ( Active Status = iota Inactive Banned ) func (s Status) String() string { return [...]string{"Active", "Inactive", "Banned"}[s] } fmt.Println(Active) // "Active" — fmt স্বয়ংক্রিয়ভাবে String() call করে fmt.Println(Banned) // "Banned"

error Interface Implementation

type AppError struct { Code int Message string } func (e *AppError) Error() string { return fmt.Sprintf("error %d: %s", e.Code, e.Message) } // Usage func GetUser(id int) (*User, error) { if id <= 0 { return nil, &AppError{Code: 400, Message: "invalid id"} } return &User{}, nil }

৮. Common Mistakes ⚠️

ভুলসমস্যাসমাধান
Value receiver-এ field পরিবর্তনcopy-তে change হয়, original অপরিবর্তিতPointer receiver ব্যবহার করুন
Mixed receiver types একই struct-এmethod set জটিল, interface satisfy কঠিনসব method-এ একই receiver type রাখুন
nil pointer-এ unchecked method callruntime panicPointer receiver-এ nil guard রাখুন
বড় struct-এ value receiverপ্রতি call-এ ব্যয়বহুল copyPointer receiver ব্যবহার করুন
self / this receiver nameGo idiom বিরোধী, code review-এ rejectছোট abbreviation ব্যবহার করুন

৯. Interview Cheat Sheet

Q: Value vs Pointer Receiver-এর মূল পার্থক্য?

Value receiver struct-এর copy-তে কাজ করে (read-only)। Pointer receiver original struct-এ কাজ করে (read + write)।

Q: কখন Pointer Receiver বাধ্যতামূলক?

১. struct modify করতে হলে। ২. sync.Mutex বা non-copyable type থাকলে। ৩. বড় struct-এ performance-এর জন্য।

Q: T এবং *T-এর method set কেন আলাদা?

Value T-কে সবসময় address করা যায় না (map value, interface value), তাই Go নিরাপত্তার জন্য value type-এ pointer receiver method রাখে না।

Q: Interface satisfaction-এ receiver type কীভাবে প্রভাব ফেলে?

Pointer receiver দিয়ে method define করলে শুধু *T সেই interface satisfy করে, T নয়।

Q: Nil receiver-এ method call কি valid?

হ্যাঁ — Go panic করে না যদি method-এর ভেতরে nil check থাকে। এটি একটি valid production pattern।

Q: একই struct-এ value ও pointer receiver mix করা যাবে?

Syntactically যাবে, কিন্তু করা উচিত নয়। Interface satisfaction-এ বিভ্রান্তি তৈরি হয় এবং Go team এটি discourage করে।


🧠 মনে রাখার কৌশল

মনে রাখুনমানে
Value = View onlyশুধু দেখার জন্য, পরিবর্তন নয়
Pointer = Permission to changeপরিবর্তনের অনুমতি আছে
(t T) → “একটি কপি নাও”আসল অপরিবর্তিত
(t *T) → “আসলটাই নাও”আসল পরিবর্তন হবে