Methods on Structs in Go

List Topics
February 17, 2025
No Comments
7 min read

In Go, methods are functions with a special receiver argument. A method is associated with a specific type, typically a struct, and can access the fields of that struct. Methods allow you to add behavior to structs, similar to how you’d associate methods with objects in object-oriented programming.

Step-by-Step Explanation:

1️⃣ Declaring a Method

A method is declared by defining a receiver in the function signature. The receiver is like a parameter, but it appears before the function name and allows the method to access the fields of the struct.

🔹 Example:

Go
package main

import "fmt"

// Define a struct
type Person struct {
    name string
    age  int
}

// Define a method for Person struct
func (p Person) greet() {
    fmt.Println("Hello, my name is", p.name)
}

func main() {
    p := Person{name: "Alice", age: 25}
    p.greet()  // Calling the method on a Person instance
}

🔹 Output:

Bash
Hello, my name is Alice

👉 In this example, the greet method is associated with the Person struct, and it can access the name field using the receiver p.

2️⃣ Pointer Receiver vs. Value Receiver

  • Value Receiver: When a method has a value receiver, it operates on a copy of the struct, so any changes made within the method will not affect the original struct.
  • Pointer Receiver: A pointer receiver allows the method to modify the original struct.

🔹 Example (Value Receiver):

Go
package main

import "fmt"

type Person struct {
    name string
    age  int
}

// Value receiver method
func (p Person) updateName(newName string) {
    p.name = newName  // This won't modify the original struct
}

func main() {
    p := Person{name: "Bob", age: 30}
    p.updateName("Robert")
    fmt.Println("Name after update:", p.name)  // Name will remain "Bob"
}

🔹 Output:

Bash
Name after update: Bob

👉 Since the updateName method uses a value receiver, the original Person struct remains unchanged.

🔹 Example (Pointer Receiver):

Go
package main

import "fmt"

type Person struct {
    name string
    age  int
}

// Pointer receiver method
func (p *Person) updateName(newName string) {
    p.name = newName  // This modifies the original struct
}

func main() {
    p := Person{name: "Bob", age: 30}
    p.updateName("Robert")
    fmt.Println("Name after update:", p.name)  // Name is now "Robert"
}

🔹 Output:

Bash
Name after update: Robert

👉 By using a pointer receiver (*Person), the updateName method modifies the original Person struct.

3️⃣ Defining Multiple Methods on a Struct

You can define multiple methods for the same struct, each providing different behavior.

🔹 Example:

Go
package main

import "fmt"

// Define a struct
type Rectangle struct {
    width  float64
    height float64
}

// Method to calculate the area of the rectangle
func (r Rectangle) area() float64 {
    return r.width * r.height
}

// Method to calculate the perimeter of the rectangle
func (r Rectangle) perimeter() float64 {
    return 2 * (r.width + r.height)
}

func main() {
    rect := Rectangle{width: 5, height: 10}
    fmt.Println("Area:", rect.area())         // Call area method
    fmt.Println("Perimeter:", rect.perimeter()) // Call perimeter method
}

🔹 Output:

Bash
Area: 50
Perimeter: 30

👉 Here, we have two methods (area and perimeter) associated with the Rectangle struct, allowing us to calculate its area and perimeter.

4️⃣ Methods with Different Receivers

You can define methods with either value or pointer receivers based on the behavior you need. Pointer receivers are used when you need to modify the original struct, while value receivers are used when no modification is needed.

🔹 Example:

Go
package main

import "fmt"

type Counter struct {
    value int
}

// Method with value receiver (no modification)
func (c Counter) display() {
    fmt.Println("Counter value:", c.value)
}

// Method with pointer receiver (modifies original struct)
func (c *Counter) increment() {
    c.value++
}

func main() {
    c := Counter{value: 10}
    c.display()     // Displays the value
    c.increment()   // Increments the value
    c.display()     // Displays the updated value
}

🔹 Output:

Bash
Counter value: 10
Counter value: 11

👉 The display method uses a value receiver because it doesn’t modify the struct, while increment uses a pointer receiver to modify the original struct.

5️⃣ Methods and Interfaces

In Go, interfaces are a way to define a set of method signatures. Any type (like a struct) that implements those methods is considered to implement the interface. Methods are a key part of Go's interface system.

🔹 Example:

Go
package main

import "fmt"

// Define an interface
type Shape interface {
    area() float64
    perimeter() float64
}

// Define a struct that implements the Shape interface
type Rectangle struct {
    width  float64
    height float64
}

// Implement the methods required by the Shape interface
func (r Rectangle) area() float64 {
    return r.width * r.height
}

func (r Rectangle) perimeter() float64 {
    return 2 * (r.width + r.height)
}

func main() {
    var s Shape
    s = Rectangle{width: 5, height: 10}

    fmt.Println("Area:", s.area())         // Interface method call
    fmt.Println("Perimeter:", s.perimeter()) // Interface method call
}

🔹 Output:

Bash
Area: 50
Perimeter: 30

👉 Here, Rectangle implements the Shape interface by providing the area and perimeter methods.

Summary:

  • Methods in Go are functions with a special receiver argument, allowing you to associate behavior with a type (such as a struct).
  • You can use either value receivers (operating on a copy of the struct) or pointer receivers (operating on the original struct).
  • Multiple methods can be defined for the same struct to implement various behaviors.
  • Methods are essential when working with interfaces in Go.

Go তে Structs এর উপর Methods

Go তে methods এমন ফাংশন যা একটি বিশেষ receiver argument থাকে। একটি method একটি নির্দিষ্ট type এর সাথে সংযুক্ত থাকে, সাধারণত struct এর সাথে, এবং সেই struct এর fields গুলিকে অ্যাক্সেস করতে পারে। Methods struct গুলির সাথে behavior যোগ করার জন্য ব্যবহার করা হয়, যেমন আপনি object-oriented programming এ objects এর সাথে methods সংযুক্ত করেন।

Step-by-Step ব্যাখ্যা:

1️⃣ Method ঘোষণা করা

একটি method ঘোষণা করা হয় ফাংশনের সিগনেচারে receiver দিয়ে। receiver একটি প্যারামিটার এর মতো, তবে এটি ফাংশন নামের আগে থাকে এবং method কে struct এর fields অ্যাক্সেস করার সুযোগ দেয়।

🔹 উদাহরণ:

Go
package main

import "fmt"

// একটি struct সংজ্ঞায়িত করা
type Person struct {
    name string
    age  int
}

// Person struct এর জন্য একটি method সংজ্ঞায়িত করা
func (p Person) greet() {
    fmt.Println("Hello, my name is", p.name)
}

func main() {
    p := Person{name: "Alice", age: 25}
    p.greet()  // Person instance এর উপর method কল করা
}

🔹 আউটপুট:

Bash
Hello, my name is Alice

👉 এই উদাহরণে, greet method টি Person struct এর সাথে সংযুক্ত এবং এটি receiver p ব্যবহার করে name field অ্যাক্সেস করতে পারে।

2️⃣ Pointer Receiver এবং Value Receiver

  • Value Receiver: যখন একটি method এর value receiver থাকে, এটি struct এর একটি কপি এর উপর কাজ করে, তাই method এর মধ্যে করা কোন পরিবর্তন আসল struct কে প্রভাবিত করবে না।
  • Pointer Receiver: একটি pointer receiver method কে আসল struct টি পরিবর্তন করার সুযোগ দেয়।

🔹 উদাহরণ (Value Receiver):

Go
package main

import "fmt"

type Person struct {
    name string
    age  int
}

// Value receiver method
func (p Person) updateName(newName string) {
    p.name = newName  // আসল struct পরিবর্তন হবে না
}

func main() {
    p := Person{name: "Bob", age: 30}
    p.updateName("Robert")
    fmt.Println("Name after update:", p.name)  // নাম অপরিবর্তিত থাকবে "Bob"
}

🔹 আউটপুট:

Bash
Name after update: Bob

👉 যেহেতু updateName method টি value receiver ব্যবহার করছে, আসল Person struct অপরিবর্তিত থাকে।

🔹 উদাহরণ (Pointer Receiver):

Go
package main

import "fmt"

type Person struct {
    name string
    age  int
}

// Pointer receiver method
func (p *Person) updateName(newName string) {
    p.name = newName  // আসল struct পরিবর্তন হবে
}

func main() {
    p := Person{name: "Bob", age: 30}
    p.updateName("Robert")
    fmt.Println("Name after update:", p.name)  // নাম এখন "Robert"
}

🔹 আউটপুট:

Bash
Name after update: Robert

👉 pointer receiver (*Person) ব্যবহার করার মাধ্যমে updateName method আসল Person struct কে পরিবর্তন করে।

3️⃣ একটি Struct এর উপর একাধিক Method সংজ্ঞায়িত করা

একই struct এর জন্য আপনি একাধিক method সংজ্ঞায়িত করতে পারেন, প্রতিটি ভিন্ন ভিন্ন আচরণ প্রদান করার জন্য।

🔹 উদাহরণ:

Go
package main

import "fmt"

// একটি struct সংজ্ঞায়িত করা
type Rectangle struct {
    width  float64
    height float64
}

// Rectangle এর area হিসাব করার জন্য method
func (r Rectangle) area() float64 {
    return r.width * r.height
}

// Rectangle এর perimeter হিসাব করার জন্য method
func (r Rectangle) perimeter() float64 {
    return 2 * (r.width + r.height)
}

func main() {
    rect := Rectangle{width: 5, height: 10}
    fmt.Println("Area:", rect.area())         // area method কল করা
    fmt.Println("Perimeter:", rect.perimeter()) // perimeter method কল করা
}

🔹 আউটপুট:

Bash
Area: 50
Perimeter: 30

👉 এখানে, আমরা দুটি method (area এবং perimeter) সংজ্ঞায়িত করেছি যা Rectangle struct এর সাথে সংযুক্ত এবং এটি এর area এবং perimeter হিসাব করতে সাহায্য করে।

4️⃣ বিভিন্ন Receiver সহ Methods

আপনি value অথবা pointer receivers দিয়ে method সংজ্ঞায়িত করতে পারেন, নির্ভর করছে কোন আচরণ প্রয়োজন। pointer receivers ব্যবহার করা হয় যখন আপনাকে আসল struct পরিবর্তন করতে হয়, আর value receivers ব্যবহার করা হয় যখন কোনো পরিবর্তন প্রয়োজন নয়।

🔹 উদাহরণ:

Go
package main

import "fmt"

type Counter struct {
    value int
}

// Value receiver সহ method (কোনো পরিবর্তন নয়)
func (c Counter) display() {
    fmt.Println("Counter value:", c.value)
}

// Pointer receiver সহ method (আসল struct পরিবর্তন করে)
func (c *Counter) increment() {
    c.value++
}

func main() {
    c := Counter{value: 10}
    c.display()     // মান প্রদর্শন করবে
    c.increment()   // মান বাড়াবে
    c.display()     // আপডেট করা মান প্রদর্শন করবে
}

🔹 আউটপুট:

Bash
Counter value: 10
Counter value: 11

👉 display method টি value receiver ব্যবহার করে কারণ এটি struct কে পরিবর্তন করে না, এবং increment method টি pointer receiver ব্যবহার করে কারণ এটি আসল struct কে পরিবর্তন করে।

5️⃣ Methods এবং Interfaces

Go তে, interfaces একটি method সিগনেচারের সেট সংজ্ঞায়িত করার উপায়। যেকোনো type (যেমন struct) যদি ঐ methods গুলি ইমপ্লিমেন্ট করে, তবে সেটি ঐ interface ইমপ্লেমেন্ট করে বলে গণ্য হয়। Methods Go এর interface সিস্টেমের একটি গুরুত্বপূর্ণ অংশ।

🔹 উদাহরণ:

Go
package main

import "fmt"

// একটি interface সংজ্ঞায়িত করা
type Shape interface {
    area() float64
    perimeter() float64
}

// একটি struct যা Shape interface ইমপ্লেমেন্ট করে
type Rectangle struct {
    width  float64
    height float64
}

// Shape interface এর জন্য প্রয়োজনীয় methods ইমপ্লেমেন্ট করা
func (r Rectangle) area() float64 {
    return r.width * r.height
}

func (r Rectangle) perimeter() float64 {
    return 2 * (r.width + r.height)
}

func main() {
    var s Shape
    s = Rectangle{width: 5, height: 10}

    fmt.Println("Area:", s.area())         // Interface method কল
    fmt.Println("Perimeter:", s.perimeter()) // Interface method কল
}

🔹 আউটপুট:

Bash
Area: 50
Perimeter: 30

👉 এখানে, Rectangle struct টি Shape interface ইমপ্লেমেন্ট করেছে area এবং perimeter methods প্রদান করে।

সারাংশ:

  • Go তে methods হলো এমন functions যা একটি বিশেষ receiver argument নিয়ে আসে, যেটি একটি type (যেমন struct) এর সাথে সংযুক্ত থাকে এবং তার behavior যোগ করতে সাহায্য করে।
  • আপনি value receivers (যেগুলি struct এর কপি এর উপর কাজ করে) অথবা pointer receivers (যেগুলি আসল struct এর উপর কাজ করে) ব্যবহার করতে পারেন।
  • একই struct এর উপর একাধিক method সংজ্ঞায়িত করা যেতে পারে, প্রতিটি আলাদা behavior প্রদান করার জন্য।
  • Methods Go তে interfaces এর সাথে কাজ করার জন্য অপরিহার্য।
©2025 Linux Bangla | Developed & Maintaind by Linux Bangla.