একটি মেথড হলো এমন একটি ফাংশন, যার একটি বিশেষ রিসিভার আর্গুমেন্ট থাকে।
রিসিভারটি নিজের আলাদা আর্গুমেন্ট তালিকায় func কিওয়ার্ড আর মেথডের নামের মাঝখানে বসে।
func (receiver type) MethodName(parameters) (returnTypes) {
}
আপনি কেবল এমন রিসিভার দিয়ে মেথড ডিফাইন করতে পারেন, যার টাইপ মেথডটির মতো একই প্যাকেজে ডিফাইন করা হয়েছে।
package person
type Person struct {
Name string
}
func (p Person) Greetings() string {
return fmt.Sprintf("Welcome %s!", p.Name)
}
স্ট্রাক্টের ওপর থাকা মেথডটি ডট নোটেশন দিয়ে কল করা যায়।
p := Person{Name: "Bronson"}
fmt.Println(p.Greetings())
// Output: Welcome Bronson!
লক্ষ্য করুন, p নামের Person ইনস্ট্যান্সে আমরা Greetings() মেথডটি যেভাবে কল করেছি।
অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং ভাষায় আপনি যেভাবে মেথড কল করেন, এটি ঠিক সেরকমই।
মনে রাখবেন: মেথড আসলে রিসিভার আর্গুমেন্টসহ একটি ফাংশন ছাড়া আর কিছু নয়। মেথড নামের সংঘর্ষ এড়াতে সাহায্য করে। যেহেতু একটি মেথড নির্দিষ্ট একটি রিসিভার টাইপের সঙ্গে যুক্ত থাকে, তাই ভিন্ন ভিন্ন টাইপে একই মেথডের নাম রাখা যায়।
import "math"
type rect struct {
width, height int
}
func (r rect) area() int {
return r.width * r.height
}
type circle struct {
radius int
}
func (c circle) area() float64 {
return math.Pow(float64(c.radius), 2) * math.Pi
}
রিসিভার দুই ধরনের: ভ্যালু রিসিভার আর পয়েন্টার রিসিভার।
এখন পর্যন্ত আমরা যে মেথডগুলো দেখেছি, সেগুলোর সবই ভ্যালু রিসিভার ব্যবহার করে। এর মানে হলো, মেথডে পাঠানো মানের একটি কপি তারা পায়। ফলে মেথডের ভেতরে রিসিভারে যে পরিবর্তনই করা হোক না কেন, তা কলারের কাছে দৃশ্যমান হয় না।
রিসিভার যে মানের দিকে নির্দেশ করে, সেই মান পরিবর্তন করার জন্য আপনি পয়েন্টার রিসিভার দিয়ে মেথড ডিক্লেয়ার করতে পারেন।
এজন্য টাইপের নামের আগে একটি * বসানো হয়।
উদাহরণস্বরূপ, rect টাইপের ক্ষেত্রে একটি পয়েন্টার রিসিভার *rect হিসেবে ডিক্লেয়ার করা হবে।
এ ধরনের পরিবর্তন মেথডের কলারের কাছেও দৃশ্যমান থাকে।
type rect struct {
width, height int
}
func (r *rect) squareIt() {
r.height = r.width
}
r := rect{width: 10, height: 20}
fmt.Printf("Width: %d, Height: %d\n", r.width, r.height)
// Output: Width: 10, Height: 20
r.squareIt()
fmt.Printf("Width: %d, Height: %d\n", r.width, r.height)
// Output: Width: 10, Height: 10
দ্রষ্টব্য: এই অনুশীলনীটি need-for-speed অনুশীলনীর ধারাবাহিকতা।
এই অনুশীলনীতে আপনি বিভিন্ন ধরনের রিমোট কন্ট্রোলড গাড়ির মধ্যে রেস আয়োজন করবেন। প্রতিটি গাড়ির নিজস্ব গতি এবং ব্যাটারি ড্রেনের বৈশিষ্ট্য থাকে।
গাড়িগুলো পুরোপুরি (১০০%) চার্জ করা ব্যাটারি নিয়ে শুরু করে। প্রতিবার যখন আপনি রিমোট কন্ট্রোল দিয়ে গাড়িটি চালান, তখন এটি গাড়ির গতির সমান দূরত্ব মিটারে অতিক্রম করে এবং তার ব্যাটারি ড্রেনের পরিমাণ অনুযায়ী অবশিষ্ট ব্যাটারির শতাংশ কমিয়ে দেয়।
কোনো গাড়ির ব্যাটারি যদি তার ব্যাটারি ড্রেনের শতাংশের নিচে নেমে যায়, তবে আপনি আর গাড়িটি চালাতে পারবেন না।
রিমোট কন্ট্রোলড গাড়িটিতে একটি চমৎকার LED ডিসপ্লে আছে, যেখানে দুই ধরনের তথ্য দেখা যায়:
"Driven <METERS> meters"."Battery at <PERCENTAGE>%".প্রতিটি রেস ট্র্যাকের নিজস্ব দূরত্ব থাকে। ব্যাটারি শেষ হওয়া ছাড়াই গাড়িগুলো ট্র্যাকটি শেষ করতে পারে কি না, তা দেখে তাদের পরীক্ষা করা হয়।
Car-এর উপর Drive মেথডটি তৈরি করুন, যা গাড়ির গতির ভিত্তিতে চালানো মিটারের সংখ্যা হালনাগাদ করে এবং ব্যাটারি ড্রেন অনুযায়ী ব্যাটারি কমায়:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car.Drive()
// car is now Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}
দ্রষ্টব্য: গাড়ি চালালে যদি গাড়ির ব্যাটারি 0-এর নিচে নেমে যায়, তবে গাড়িটি চালানোর চেষ্টা করা উচিত নয়।
Car-এ একটি DisplayDistance মেথড তৈরি করুন, যা LED ডিসপ্লেতে যেভাবে দেখানো হয় সেভাবে দূরত্ব একটি string হিসেবে রিটার্ন করে:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayDistance())
// Output: "Driven 0 meters"
Car-এ DisplayBattery মেথডটি তৈরি করুন, যা LED ডিসপ্লেতে যেভাবে দেখানো হয় সেভাবে ব্যাটারির শতাংশ একটি string হিসেবে রিটার্ন করে:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayBattery())
// Output: "Battery at 100%"
একটি রেস শেষ করতে হলে গাড়িটিকে রেসের দূরত্ব চালাতে সক্ষম হতে হবে।
এর মানে হলো ফিনিশ লাইন পার হওয়ার আগেই যেন তার ব্যাটারি শেষ না হয়ে যায়।
CanFinish মেথডটি তৈরি করুন, যা প্যারামিটার হিসেবে একটি trackDistance int নেয় এবং গাড়িটি রেস শেষ করতে পারলে true রিটার্ন করে; অন্যথায় false রিটার্ন করে:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
trackDistance := 100
car.CanFinish(trackDistance)
// => true
Exercism-এ সাইন আপ করুন, Go ট্র্যাকের 34টি কনসেপ্ট166টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।