In Go, interfaces define a set of method signatures but do not provide the implementation for those methods. A type is said to implement an interface if it provides implementations for all of the methods listed in the interface.
Interfaces are a crucial part of Go’s type system and are used to define behavior. They enable polymorphism and allow you to write more flexible and reusable code.
An interface in Go is declared using the type
keyword, followed by the interface name and the method signatures.
🔹 Example:
package main
import "fmt"
// Declaring an interface
type Shape interface {
area() float64
perimeter() float64
}
In this example, the Shape
interface defines two methods: area()
and perimeter()
. Any type that implements these methods is considered to satisfy the Shape
interface.
To implement an interface, a type must provide implementations for all of the methods declared by the interface.
🔹 Example:
package main
import "fmt"
// Shape interface declaration
type Shape interface {
area() float64
perimeter() float64
}
// Rectangle struct
type Rectangle struct {
width, height float64
}
// Implementing the Shape interface for Rectangle
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()) // Calling the area method
fmt.Println("Perimeter:", s.perimeter()) // Calling the perimeter method
}
🔹 Output:
Area: 50
Perimeter: 30
👉 In this example, the Rectangle
struct implements the Shape
interface by providing definitions for both the area
and perimeter
methods.
The empty interface interface{}
is a special type in Go that can hold values of any type. It doesn’t require any methods to be implemented, making it a versatile tool for handling values of unknown types.
🔹 Example:
package main
import "fmt"
func describe(i interface{}) {
fmt.Printf("Type: %T, Value: %v\n", i, i)
}
func main() {
describe(42) // Passing an integer
describe("Hello") // Passing a string
describe(true) // Passing a boolean
}
🔹 Output:
Type: int, Value: 42
Type: string, Value: Hello
Type: bool, Value: true
👉 The describe
function accepts an empty interface interface{}
, which means it can take arguments of any type.
When you have a value of an interface type and you want to retrieve its underlying concrete value, you can use a type assertion.
🔹 Example:
package main
import "fmt"
func main() {
var i interface{} = "Hello"
// Type assertion
str, ok := i.(string)
if ok {
fmt.Println("Value is a string:", str)
} else {
fmt.Println("Value is not a string")
}
}
🔹 Output:
Value is a string: Hello
👉 In this example, the type assertion i.(string)
checks if i
holds a value of type string
.
A type switch is used when you want to perform multiple type assertions on the same interface value. It’s like a regular switch statement, but it switches on the type of the interface value.
🔹 Example:
package main
import "fmt"
func describe(i interface{}) {
switch v := i.(type) {
case int:
fmt.Println("Integer:", v)
case string:
fmt.Println("String:", v)
default:
fmt.Println("Unknown type")
}
}
func main() {
describe(42)
describe("Hello")
describe(true)
}
🔹 Output:
Integer: 42
String: Hello
Unknown type
👉 The describe
function uses a type switch to handle different types of values passed to it.
Here’s a more practical example where multiple types implement the same interface, allowing for polymorphism.
🔹 Example:
package main
import "fmt"
// Shape interface
type Shape interface {
area() float64
}
// Rectangle struct
type Rectangle struct {
width, height float64
}
// Circle struct
type Circle struct {
radius float64
}
// Implementing the Shape interface for Rectangle
func (r Rectangle) area() float64 {
return r.width * r.height
}
// Implementing the Shape interface for Circle
func (c Circle) area() float64 {
return 3.14 * c.radius * c.radius
}
// Function that works with any Shape
func printArea(s Shape) {
fmt.Println("Area:", s.area())
}
func main() {
r := Rectangle{width: 5, height: 10}
c := Circle{radius: 7}
printArea(r) // Works with Rectangle
printArea(c) // Works with Circle
}
🔹 Output:
Area: 50
Area: 153.86
👉 In this example, both Rectangle
and Circle
implement the Shape
interface, and the printArea
function can work with any type that satisfies the interface.
interface{}
) can hold values of any type.Go তে Interfaces
Go-তে, ইন্টারফেস একটি পদ্ধতি সিগনেচারের সেট সংজ্ঞায়িত করে কিন্তু সেই পদ্ধতিগুলির বাস্তবায়ন প্রদান করে না। একটি ধরনের (type) ইন্টারফেসটি বাস্তবায়ন করে বলে গণ্য হয় যদি তা ইন্টারফেসে তালিকাভুক্ত সমস্ত পদ্ধতির জন্য বাস্তবায়ন প্রদান করে।
ইন্টারফেসগুলি Go-র টাইপ সিস্টেমের একটি গুরুত্বপূর্ণ অংশ এবং এগুলি আচরণ (behavior) সংজ্ঞায়িত করতে ব্যবহৃত হয়। এগুলি পলিমরফিজম সক্ষম করে এবং আপনাকে আরো নমনীয় এবং পুনঃব্যবহারযোগ্য কোড লেখার সুযোগ দেয়।
Go-তে, একটি ইন্টারফেস type
কিওয়ার্ড ব্যবহার করে ঘোষণা করা হয়, তারপর ইন্টারফেসের নাম এবং তার পদ্ধতি সিগনেচার গুলি আসে।
🔹 উদাহরণ:
package main
import "fmt"
// ইন্টারফেস ঘোষণা করা
type Shape interface {
area() float64
perimeter() float64
}
এই উদাহরণে, Shape
ইন্টারফেস দুটি পদ্ধতি ঘোষণা করেছে: area()
এবং perimeter()
। যে কোনো ধরনের (type) যদি এই পদ্ধতিগুলি বাস্তবায়ন করে, তবে তা Shape
ইন্টারফেসটি পূরণ করবে।
একটি ইন্টারফেস বাস্তবায়ন করার জন্য, একটি ধরনের (type) তার সমস্ত পদ্ধতির জন্য বাস্তবায়ন প্রদান করতে হবে।
🔹 উদাহরণ:
package main
import "fmt"
// Shape ইন্টারফেস ঘোষণা
type Shape interface {
area() float64
perimeter() float64
}
// Rectangle কাঠামো
type Rectangle struct {
width, height float64
}
// Rectangle এর জন্য Shape ইন্টারফেস বাস্তবায়ন
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()) // area পদ্ধতি কল
fmt.Println("Perimeter:", s.perimeter()) // perimeter পদ্ধতি কল
}
🔹 আউটপুট:
Area: 50
Perimeter: 30
👉 এই উদাহরণে, Rectangle
কাঠামো Shape
ইন্টারফেসটি বাস্তবায়ন করেছে area
এবং perimeter
পদ্ধতিগুলোর মাধ্যমে।
খালি ইন্টারফেস interface{}
একটি বিশেষ ধরনের ইন্টারফেস যা যেকোনো ধরনের মান ধারণ করতে পারে। এটি কোন পদ্ধতি বাস্তবায়ন করার প্রয়োজন নেই, তাই এটি অজানা ধরনের মান পরিচালনা করতে একটি বহুমুখী টুল।
🔹 উদাহরণ:
package main
import "fmt"
func describe(i interface{}) {
fmt.Printf("Type: %T, Value: %v\n", i, i)
}
func main() {
describe(42) // একটি পূর্ণসংখ্যা পাঠানো
describe("Hello") // একটি স্ট্রিং পাঠানো
describe(true) // একটি বুলিয়ান পাঠানো
}
🔹 আউটপুট:
Type: int, Value: 42
Type: string, Value: Hello
Type: bool, Value: true
👉 describe
ফাংশন একটি খালি ইন্টারফেস interface{}
গ্রহণ করে, যার মানে এটি যেকোনো ধরনের মান গ্রহণ করতে পারে।
যখন আপনার কাছে একটি ইন্টারফেস ধরনের মান থাকে এবং আপনি তার অন্তর্নিহিত কনক্রিট মান পেতে চান, তখন আপনি টাইপ অ্যাসারশন ব্যবহার করতে পারেন।
🔹 উদাহরণ:
package main
import "fmt"
func main() {
var i interface{} = "Hello"
// টাইপ অ্যাসারশন
str, ok := i.(string)
if ok {
fmt.Println("Value is a string:", str)
} else {
fmt.Println("Value is not a string")
}
}
🔹 আউটপুট:
Value is a string: Hello
👉 এই উদাহরণে, টাইপ অ্যাসারশন i.(string)
চেক করে যে i
কি একটি string
ধরনের মান ধারণ করছে কিনা।
একটি টাইপ সুইচ তখন ব্যবহার করা হয়, যখন আপনি একই ইন্টারফেস মানের উপর একাধিক টাইপ অ্যাসারশন করতে চান। এটি একটি সাধারণ switch
বিবৃতির মতো, তবে এটি ইন্টারফেস মানের টাইপে সুইচ করে।
🔹 উদাহরণ:
package main
import "fmt"
func describe(i interface{}) {
switch v := i.(type) {
case int:
fmt.Println("Integer:", v)
case string:
fmt.Println("String:", v)
default:
fmt.Println("Unknown type")
}
}
func main() {
describe(42)
describe("Hello")
describe(true)
}
🔹 আউটপুট:
Integer: 42
String: Hello
Unknown type
👉 describe
ফাংশন একটি টাইপ সুইচ ব্যবহার করে বিভিন্ন ধরনের মানের সাথে কাজ করে।
এখানে একটি আরো ব্যবহারিক উদাহরণ, যেখানে একাধিক ধরনের একই ইন্টারফেস বাস্তবায়ন করে, যার ফলে পলিমরফিজম সম্ভব হয়।
🔹 উদাহরণ:
package main
import "fmt"
// Shape ইন্টারফেস
type Shape interface {
area() float64
}
// Rectangle কাঠামো
type Rectangle struct {
width, height float64
}
// Circle কাঠামো
type Circle struct {
radius float64
}
// Rectangle এর জন্য Shape ইন্টারফেস বাস্তবায়ন
func (r Rectangle) area() float64 {
return r.width * r.height
}
// Circle এর জন্য Shape ইন্টারফেস বাস্তবায়ন
func (c Circle) area() float64 {
return 3.14 * c.radius * c.radius
}
// যে কোন Shape এর সাথে কাজ করার জন্য ফাংশন
func printArea(s Shape) {
fmt.Println("Area:", s.area())
}
func main() {
r := Rectangle{width: 5, height: 10}
c := Circle{radius: 7}
printArea(r) // Rectangle এর সাথে কাজ করছে
printArea(c) // Circle এর সাথে কাজ করছে
}
🔹 আউটপুট:
Area: 50
Area: 153.86
👉 এই উদাহরণে, Rectangle
এবং Circle
উভয়ই Shape
ইন্টারফেসটি বাস্তবায়ন করেছে, এবং printArea
ফাংশনটি যেকোনো ধরনের সাথে কাজ করতে পারে যেটি ইন্টারফেসটি পূরণ করে।
interface{}
) যেকোনো ধরনের মান ধারণ করতে পারে।