# পরিচিতি

**লেখক ও কন্ট্রিবিউটরদের তালিকা**\
[বিস্তারিত এখানে](https://github.com/howtocode-dev/golang.howtocode.dev/graphs/contributors?type=a)

Go আসলে বেশি পরিচিত golang নামেই। এটি ২০০৭ সালে Google এ ডেভেলপ করা হয়েছিল রবার্ট গ্রিজমার, রব পাইক এবং কেইন থম্পসন এর দ্বারা। ২০০৯ সালের দিকে এই ল্যাঙ্গুয়েজটি প্রকাশ করা হয়। ইতোমধ্যে এটি Google এর বেশ কিছু প্রোডাকশন সিস্টেমে ব্যবহৃত হচ্ছে। এই ল্যাঙ্গুয়েজটি মূলত ব্যাকএন্ড সিস্টেমে ব্যবহৃত হয়। অর্থাৎ, সার্ভার ও নেটওয়ার্ক সংক্রান্ত অ্যাপে।

## ওপেন সোর্স

এই বইটি মূলত স্বেচ্ছাশ্রমে লেখা এবং বইটি সম্পূর্ন ওপেন সোর্স । এখানে তাই আপনিও অবদান রাখতে পারেন লেখক হিসেবে । আপনার কন্ট্রিবিউশান গৃহীত হলে অবদানকারীদের তালিকায় আপনার নাম যোগ করে দেওয়া হবে ।

এটি মূলত একটি [গিটহাব রিপোজিটোরি](https://github.com/howtocode-dev/golang.howtocode.dev) যেখানে এই বইয়ের আর্টিকেল গুলো মার্কডাউন ফরম্যাটে লেখা হচ্ছে । রিপোজটরিটি ফর্ক করে পুল রিকুয়েস্ট পাঠানোর মাধ্যমে আপনারাও অবদান রাখতে পারেন । বিস্তারিত দেখতে পারেন [এই ভিডিওতে](http://blog.howtocode.com.bd/?p=32)

> **বর্তমানে বইটির কন্টেন্ট বিভিন্ন কন্ট্রিবিউটর এবং নানা রকম সোর্স থেকে সংগৃহীত এবং সংকলিত।**

\
This work is licensed under a [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License](http://creativecommons.org/licenses/by-nc-nd/4.0/).


# শুরুর আগে

শুরু করার আগে আমাদের প্রথমেই গো সেটাপ করে নেওয়া এবং এর বিল্টইন টুল গুলো সম্পর্কে জানা প্রয়োজন। তার আগে গো সম্পর্কে কিছু বলে রাখা দরকার।

গো স্ট্যাটিকালি স্ট্রংলি টাইপ ল্যাঙ্গুয়েজ, পাইথনের মত গোতে যেকোনো ভ্যারিয়েবলে যেকোনো কিছু রাখা যায় না। গো কম্পাইলড প্রোগ্রামিং ল্যাঙ্গুয়েজ, অর্থাৎ এতে লিখা প্রোগ্রাম বাইনারিতে কনভার্ট হয় এবং সেই বাইনারি ফাইল চালাতে হয়। সে জন্য গো বেশ দ্রুত কাজ করে। এমনিতেই কম্পাইলার ভিত্তিক ল্যাঙ্গুয়েজ সবসময়ই ইন্টারপ্রেটার ভিত্তিক ল্যাঙ্গুয়েজ এর চেয়ে ফাস্ট হয়। তবে গো, সি বা সি++ বাদে প্রায় সব ল্যাঙ্গুয়েজের চেয়েই ফাস্ট।\
গো সিনট্যাক্সের দিক দিয়ে সি এর মতই। কিন্তু গো আরও কিছু সুবিধা দেয়, যেমন মেমোরি সেফটি, গারবেজ কালেকশন, কনকারেন্সি। গো তৈরি করার সময় ডেভেলপররা অন্য ল্যাঙ্গুয়েজের ভালো বৈশিষ্ট্যগুলো সমন্বয়ের বিষয়টি মাথায় রেখেছিলেন, তাই গো দেয় সি এর মত স্ট্যাটিক টাইপিং এবং দ্রুততার সুবিধা, পাইথন বা জাভাস্ক্রিপ্টের মত সহজবোধ্যতা আর দেয় নেটওয়ার্কিং ও মাল্টিপ্রোসেসিং এর সুবিধা।

> “Go is like a better C, from the guys that didn’t bring you C++” — Ikai Lan

## ইনস্টলেশন

যারা ম্যাক ওসএক্স ব্যবহার করেন, তাদের জন্য হোমব্রু ব্যবহার করে ইনস্টল করা খুবই সহজ:

```
brew install go
```

যারা উবুন্টু ব্যবহার করেন, তারা `apt` ব্যবহার করে `go` ইনস্টল করতে পারেন:

```
sudo apt install golang
```

এছাড়া সব প্লাটফর্মের জন্য গো ডাউনলোড করা যাবে [এখান থেকে](https://golang.org/dl/)।

## গো প্রোগ্রাম রান করা

গো প্রোগ্রাম রান করা খুবই সহজ, আমাদের মূল গো ফাইলের নাম যদি হয় `main.go` তাহলে টার্মিনালে এই কমান্ডটি ব্যবহার করে আমরা প্রোগ্রামটি রান করাতে পারবো:

```
go run main.go
```

সবকিছু ঠিক থাকলে এখন আমরা গো তে আমাদের প্রথম প্রোগ্রামটি লিখার জন্য প্রস্তুত!


# হ্যালো গো

একটি গো প্রোগ্রাম শুরু হয় `package` কিওয়ার্ডটি দিয়ে। প্যাকেজিং বিষয়ে আমরা পরবর্তীতে আরো বিস্তারিত জানবো। আপাতত আমাদের প্যাকেজের নাম ধরে নেই `main`। প্রোগ্রাম `main` প্যাকেজ থেকে রান শুরু করে। প্যাকেজ ডিফাইন করার পর আমরা `fmt` মডিউলটি ইম্পোর্ট করে নেই। এই মডিউলে স্ট্রিং ফরম্যাটিং সংশ্লিষ্ট ফাংশন থাকে। এর `Println` ফাংশনটি ব্যবহার করে আমরা আউটপুট দিতে পারি।

কোড স্যাম্পল:

```go
package main

import "fmt"

func main() {
    fmt.Println("hello, পৃথিবী!")
}
```

এবার প্রোগ্রামটি রান করি:

```
$ go run hello.go
hello, পৃথিবী!
```

ব্যাস, আমরা আমাদের প্রথম গো প্রোগ্রামটি লিখে ফেললাম এবং রান করে দেখলাম :)


# ভ্যালুজ

গো তে বেশ কয়েক ধরনের ভ্যালু টাইপ আছে । এর মধ্যে স্ট্রিং, ইন্টিজার, ফ্লোট, বুলিয়ান ইত্যাদি উল্লেখযোগ্য । আগের চ্যাপ্টারে দেখা `Println` ফাংশনটি ব্যবহার করে কিছু বেসিক টাইপ প্রিন্ট করে দেখি:

```go
package main

import "fmt"

func main() {

    // দুইটা স্ট্রিং আমরা `+` ব্যবহার করে জোড়া লাগাতে পারি
    fmt.Println("go" + "lang")

    // ইন্টিজার ও ফ্লোটিং পয়েন্ট নাম্বার 
    fmt.Println("1+1 =", 1+1)
    fmt.Println("7.0/3.0 =", 7.0/3.0)

    // বুলিয়ান টেস্ট 
    fmt.Println(true && false)
    fmt.Println(true || false)
    fmt.Println(!true)
}
```

আউটপুট:

```
$ go run main.go
golang
1+1 = 2
7.0/3.0 = 2.3333333333333335
false
true
false
```

## ইন্টিজার

গো তে প্রতিটি ভ্যালু টাইপের মধ্যে কিছু ভাগ আছে। যেমন ইন্টিজার টাইপের জন্য আছে `uint8, int8, uint16, int16, uint32, int32, uint64, int64`। শেষের সংখ্যা বুঝায় কত বিট জায়গা ব্যবহার করবে। আরও তিনটি ইন্টিজার টাইপ আছে, এরা মেশিন ডিপেন্ডেনট:`uint, int and uintptr`। এদের মেশিন ডিপেন্ডেন্ট বলা হচ্ছে কারণ কত বিট জায়গা নেবে তা কম্পিউটারের আর্কিটেকচারের উপর নির্ভর করছে।

## ফ্লোটিং পয়েন্ট নাম্বার

দশমিক সংখ্যার জন্য গো তে আছে `float32` আর `float64`। জটিল সংখ্যার জন্য `complex64` আর `complex128`।

## স্ট্রিং

টেক্সটের জন্য স্ট্রিং টাইপ ব্যবহার হয়। গো এর স্ট্রিং ইউনিকোড সাপোর্ট করে। অর্থাৎ যেকোনো ভাষায় লিখা যায়।

## বুলিয়ান

১ বিটের ইন্টিজার, `True` আর `False` প্রকাশ করে।


# ভ্যারিয়েবলস

গো তে ভ্যারিয়েবল গুলো এক্সপ্লিসিটলি ডিফাইন করে দিতে হয়। এজন্য একে স্ট্যাটিকালি টাইপ ল্যাঙ্গুয়েজ বলে। `var` কিওয়ার্ডটি ব্যবহার করে আমরা এক বা একাধিক ভ্যারিয়েবল ডিফাইন করতে পারি। এই কিওয়ার্ডটির পর ভ্যারিয়েবল এর নাম এবং তারপর টাইপ নির্দেশ করতে হয়। টাইপের জন্য আমরা আগের অধ্যায়ে যেসব টাইপ শিখেছি সেগুলো ব্যবহার করি।

একই টাইপের একাধিক ভ্যারিয়েবল কমা দিয়ে সেপারেট করে দিয়ে সবগুলোকে একই সাথে ডিফাইন করা সম্ভব। এছাড়া যদি আমরা টাইপ উহ্য রাখি সেক্ষেত্রে গো ভ্যালু থেকে টাইপ অনুমান করে নেয়। এছাড়া শর্টহ্যান্ড সিনট্যাক্স ব্যবহার করে `var` কিওয়ার্ড ও টাইপ ডিক্লেয়ারেশন ছাড়াই ভ্যারিয়েবল তৈরি করা সম্ভব।

নিচের কোড ব্লকে আমরা ভ্যারিয়েবল সংশ্লিষ্ট কিছু উদাহরণ দেখবো:

```go
package main

import "fmt"

func main() {

    // `var` এর মাধ্যমে আমরা এক বা একাধিক ভ্যারিয়েবল তৈরি করতে পারি
    var a string = "initial"
    fmt.Println(a)

    // এক সাথে অনেকগুলো ভ্যারিয়েবল ও ডিফাইন করা সম্ভব 
    var b, c int = 1, 2
    fmt.Println(b, c)

    // টাইপ উল্লেখ না করলে গো নিজে থেকেই টাইপ অনুমান করে নেয়
    var d = true
    fmt.Println(d)

    // ভ্যালু না দেওয়া থাকলে "জিরো ভ্যালু" ধরে নেওয়া হয়
    var e int
    fmt.Println(e)

    // শর্টহ্যান্ড `:=` সিনট্যাক্স ব্যবহার করে টাইপ ছাড়াই 
    // ভ্যারিয়েবল ডিফাইন ও ডিক্লেয়ার করা যায়
    f := "short"
    fmt.Println(f)
}
```

আউটপুট:

```
initial
1 2
true
0
short
```


# কন্সট্যান্টস

গো তে কনস্ট্যান্টস ডিফাইন করার জন্য `const` কিওয়ার্ডটি ব্যবহার করি আমরা । এই কিওয়ার্ডটির পর কনস্ট্যান্ট এর নাম এবং তারপর এটির ভ্যালু এ্যাসাইন করি ।

আমরা যেসব জায়গায় `var` ব্যবহার করতে পারি তার সব জায়গাতেই কনস্ট্যান্ট ডিফাইন করা সম্ভব ।

```go
package main

import "fmt"

// কনস্ট্যান্ট ডিক্লেয়ারেশন
const s string = "constant"

func main() {
    fmt.Println(s)
    const n = 500000000
    fmt.Println(n)
}
```

আউটপুট:

```
constant
500000000
```


# ফর

অন্য সব ল্যাঙ্গুয়েজে আমরা `ফর` লুপ দেখেছি। মজার ব্যাপার হচ্ছে গো তে সব ধরণের লুপিংই `ফর` দিয়ে করা হয়। অর্থাৎ গো তে `হোয়াইল`, `ডু-হোয়াইল` কিংবা `ফর-ইচ` লুপ দেখা যায় না। কিন্তু এগুলোর কাজ আমরা `ফর` দিয়েই চালিয়ে নিতে পারি বেশ সহজেই!

## ফর লুপ

আমরা প্রথমেই আমাদের পরিচিত ফর লুপ টা দেখে নেই। এখানে:

```go
for j := 7; j <= 9; j++ {
    fmt.Println(j)
}
```

আউটপুট:

```
7
8
9
```

এটা আমাদের সবার পরিচিত `ফর` লুপ। এখানে `j` এর ভ্যালু শুরুতেই 7 দেওয়া হয়েছে, এর ভ্যালু ৯ হওয়া পর্যন্ত লুপ চলবে। প্রতিবার লুপ শেষে `j` এর ভ্যালু এক বাড়িয়ে দেওয়া হচ্ছে।

## হোয়াইল লুপ

অন্য নানা ল্যাঙ্গুয়েজে একটা শর্তের উপর নির্ভর করে যেভাবে হোয়াইল লুপ ব্যবহার করতাম, গো তেও আমরা কাজটা প্রায় একইভাবে করবো। শুধু পার্থক্য এখানে আমরা `ফর` কিওয়ার্ডটি ব্যবহার করে `হোয়াইল` লুপের কাজ করি।

```go
package main

import "fmt"

func main() {

    i := 1
    for i <= 3 {
        fmt.Println(i)
        i = i + 1
    }


}
```

আউটপুট:

```
1
2
3
```

প্রথমে `for` এবং তারপর মূল কন্ডিশন দিতে হয়। লক্ষ্য করুন এখানে `for` এর কন্ডিশনটি ডিফাইন করার সময় কোন ধরনের ব্র্যাকেট এর প্রয়োজন হয় নি। `ফর` এর পর যদি একটাই শর্ত দেওয়া হয় তবে ঐ শর্তটি যতক্ষণ সত্য হবে ততক্ষণ লুপটি চলতে থাকবে।

যদি আমরা কোন কন্ডিশন না দেই তাহলে এটা ইনফিনিট লুপ এ চলতে থাকবে।

```go
for {
    fmt.Println("infinite loop")
    break
}
```

আউটপুট:

```
infinite loop
```

লক্ষ করুন, `break` কি-ওয়ার্ড ব্যবহার করার জন্য লুপটি একবার চলেই থেমে গেছে।

## ফর ইচ লুপ

গো তে আমরা `ফর` লুপ ব্যবহার করেই ফর ইচ লুপের কাজ করে থাকি। এটির জন্য প্রয়োজন পড়ে `range` ফাংশনের। আমরা তাই `range` চ্যাপ্টারে দেখবো কিভাবে আমরা ফর ইচ ব্যবহার করতে পারি।


# ইফ/এলস

অন্যান্য প্রোগ্রামিং ল্যাঙ্গুয়েজের মতই গো তে ইফ এলস কাজ করে। একটা সিম্পল উদাহরন দেখি:

```go
    if 7%2 == 0 {
        fmt.Println("7 is even")
    } else {
        fmt.Println("7 is odd")
    }
```

আগে `ফর` চ্যাপ্টারে দেখেছি গো তে কন্ডিশন ব্র্যাকেটের রাখার প্রয়োজন পড়ে না। ইফ এলস এর বেলায়ও তাই। ইফ স্টেটমেন্টের পর সরাসরি আমরা কন্ডিশন লিখে দেই। ব্র্যাকেটের প্রয়োজন নেই।

আমরা চাইলে ইফ স্টেটমেন্ট এর পর এবং মূল কন্ডিশনের আগে আমাদের প্রয়োজনমত অন্য কোন এক্সপ্রেশন ব্যবহার করতে পারি। এখানে ডিক্লেয়ার করা কোন ভ্যারিয়েবল ইফ-এলস এর সকল ব্র্যানচ এ এ্যাক্সেসিবল হবে।

```go
    if num := 9; num < 0 {
        fmt.Println(num, "is negative")
    } else if num < 10 {
        fmt.Println(num, "has 1 digit")
    } else {
        fmt.Println(num, "has multiple digits")
    }
```

এখানে আমাদের মূল কন্ডিশন হলো `num < 0` কিন্তু তার আগে আমরা `num` এর ভ্যালু `9` সেট করে নিয়েছি। লক্ষ্য করুন সব গুলো ব্লকেই কিন্তু `num` ভ্যারিয়েবলটি এ্যাক্সেস করা যাচ্ছে। আউটপুট:

```
9 has 1 digit
```

এই উদাহরনে আমরা `else if` এর ব্যবহার ও দেখলাম। একাধিক কন্ডিশন চেক করার জন্য আমরা ইফ এর সাথে এই এলস-ইফ ব্যবহার করি।

গো তে টার্নারী অপারেটর এর কনসেপ্ট নেই, তাই যত সংক্ষিপ্ত লজিকই হোক, পুরো ইফ-এলস ব্লক লিখতে হবে, কোন শর্টকাট নেই।


# সুইচ

সুইচ স্টেটমেন্ট এর ব্যাসিক এক্সাম্পল দেখে নেই:

```go
    i := 2
    fmt.Print("write ", i, " as ")
    switch i {
    case 1:
        fmt.Println("one")
    case 2:
        fmt.Println("two")
    case 3:
        fmt.Println("three")
    }
```

এখানে আমার সুইচ স্টেটমেন্টকে একটি এক্সপ্রেশন দিয়ে দেই। এরপর সেই এক্সপ্রেশনের ভ্যালুর সাথে আমাদের কেইসগুলো ম্যাচ করিয়ে দেখি যে শর্ত মেলে কিনা। যে সব কেইস ম্যাচ করে সেইসব কেইসের সাথে থাকা কোড ব্লক রান করে। উপরের কোডের আউটপুট হবে:

```
write 2 as two
```

আমরা কেইস স্টেটমেন্ট এ কমা দিয়ে একাধিক কন্ডিশন দিয়ে দিতে পারি, যেমন:

```go
package main

import "fmt"
import "time"

func main() {
    switch time.Now().Weekday() {
    case time.Friday, time.Saturday:
        fmt.Println("it's the weekend")
    default:
        fmt.Println("it's a weekday")
    }
}
```

আমার জন্য আউটপুট আসছে:

```
it's a weekday
```

যেদিন লিখছি সেদিন বৃহস্পতিবার, তাই :|

তবে সুইচ স্টেটমেন্ট এর পাশাপাশি কেইস স্টেটমেন্ট এও আমরা ডাইনামিক এক্সপ্রেশন ব্যবহার করতে পারি। আমরা চাইলে সুইচ স্টেটমেন্টে কোন এক্সপ্রেশন পাস নাও করতে পারি, সেক্ষেত্রে সুইচ কে ইফ-এলস এর মত করে ব্যবহার করা যায় -

```go
package main

import "fmt"
import "time"

func main() {
    t := time.Now()
    switch {
    case t.Hour() < 12:
        fmt.Println("it's before noon")
    default:
        fmt.Println("it's after noon")
    }
}
```

এখানে দেখুন `case t.Hour() < 12` ডাইনামিক এক্সপ্রেশন। এবং আমরা সুইচ স্টেটমেন্টে `t` কে পাস না করে, কেইস স্টেটমেন্টে এসে সরাসরি `t.Hour()` ব্যবহার করেছি। জিনিসটা ইফ-এলস দিয়ে আমরা এভাবে করতে পারতাম:

```go
package main

import "fmt"
import "time"

func main() {
    t := time.Now()
    if t.Hour() < 12 {
        fmt.Println("it's before noon")
    }

}
```


# এ্যারে

গো ল্যাঙ্গুয়েজে এ্যারে হলো একই ধরনের আইটেমের সমষ্টি বা তালিকা। এবং এর আইটেম সংখ্যা নির্দিষ্ট থাকে। অর্থাৎ এ্যারে হয় ফিক্সড সাইজ।

এ্যারে ডিফাইন করা খুবই সহজ। প্রথমে `var` কিওয়ার্ড, এরপর ভ্যারিয়েবল এর নাম এবং শেষে স্কোয়ার ব্র্যাকেট `[]` এর মধ্যে এ্যারের সাইজ এবং ব্র্যাকেট শেষে এ্যারের টাইপ।

```go
var a [5]int
```

এখানে `a` হলো একটি এ্যারে যেখানে আমরা ৫টি ইন্টিজার ভ্যালু সংরক্ষণ করতে পারি। গো ও জিরো বেইজড ইনডেক্স ফলো করে। অর্থাৎ প্রথম এলিমেন্টটির পজিশন হয় `0`। সুতরাং শেষ এলিমেন্টটি আমরা এ্যাক্সেস করতে পারি এভাবে -

```go
a[4] = 100
fmt.Println("get:", a[4])
```

আউটপুট:

```
get: 100
```

এখানে আমরা শেষ এলিমেন্টটির ভ্যালু হিসেবে `100` সেট করে দিচ্ছি। বিল্ট ইন `len` ফাংশনটি ব্যবহার করে আমরা এ্যারের সাইজ জানতে পারি।

```go
fmt.Println("len:", len(a))
```

আউটপুট:

```
len: 5
```

আমরা চাইলে এ্যারে ডিক্লেয়ারেশনের পর কার্লি ব্রেইসের মধ্যে আইটেম গুলো ডিফাইন করে দিতে পারি। এভাবে আমরা নিচের মত করে একই সাথে এ্যারে ডিক্লেয়ার এবং তার ভ্যালুগুলো সেট করে দেই:

```go
b := [5]int{1, 2, 3, 4, 5}
fmt.Println("dcl:", b)
```

আউটপুট:

```
dcl: [1 2 3 4 5]
```

মাল্টিডাইমেনশনাল এ্যারের জন্য প্রয়োজনীয় সংখ্যক স্কোয়ার ব্র্যাকেট যোগ করে সেগুলোর মধ্যে ঐ ডাইমেনশনে আইটেম সংখ্যা নির্দেশ করলেই হয়। যেমন:

```go
var twoD [2][3]int
```

আমরা এর ভ্যালু গুলো ফর লুপ ব্যবহার করে এ্যাসাইন করে দিতে পারি:

```go
    for i := 0; i < 2; i++ {
        for j := 0; j < 3; j++ {
            twoD[i][j] = i + j
        }
    }
    fmt.Println("2d: ", twoD)
```

আউটপুট:

```
2d:  [[0 1 2] [1 2 3]]
```

তবে সাধারনত গো তে আমরা এ্যারের চেয়ে স্লাইস বেশি ব্যবহার করে থাকি। পরবর্তী চ্যাপ্টারে আমরা স্লাইস নিয়ে দেখবো।


# স্লাইসেস

গো তে স্লাইস খুবই পাওয়ারফুল একটা ডাটা স্ট্রাকচার। এ্যারে যেখানে ফিক্সড লেংথ এর হয়, স্লাইস এর এরকম কোন লিমিটেশন নেই। তবে এ্যারের মত স্লাইসের ক্ষেত্রেও আমাদের টাইপ নির্দিষ্ট করে দিতে হয়।

আমরা `make` ফাংশনটি ব্যবহার করে স্লাইস তৈরি করতে পারি:

```go
s := make([]string, 3)
fmt.Println("emp:", s)
```

এখানে আমরা একটি স্লাইস তৈরি করেছি যেটিতে আমরা স্ট্রিং স্টোর করবো এবং ইনিশিয়ালি ৩টি আইটেমের জন্য মেমোরী এ্যালোকেট করা হবে। এই ৩টি আইটেমের ইনিশিয়াল ভ্যালু হবে "জিরো ভ্যালু" - অর্থাৎ সংশ্লিস্ট টাইপ (এক্ষেত্রে স্ট্রিং) এর শুন্যর সম মানের ভ্যালু। স্ট্রিং এর ক্ষেত্রে জিরো ভ্যালু হলো ফাকা স্ট্রিং।

আউটপুট:

```
emp: [  ]
```

আমরা এ্যারের মত করেই ইনডেক্স ব্যবহার করে স্লাইসের আইটেমগুলো এ্যাক্সেস করতে পারি:

```go
fmt.Println("set:", s)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("get:", s[2])
```

আউটপুট:

```
set: [  ]
get: c
```

স্লাইসের লেংথ জানতে আমরা `len` ফাংশনটি ব্যবহার করি:

```go
fmt.Println("len:", len(s))
```

আউটপুট:

```
len: 3
```

এবং স্লাইসের শেষে যোগ করতে আমরা `append` ফাংশনটি ব্যবহার করতে পারি:

```go
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println("apd:", s)
```

আউটপুট:

```
apd: [a b c d e f]
```

`copy` ফাংশনটি ব্যবহার করে আমরা স্লাইস টু স্লাইস কপি করতে পারি:

```go
c := make([]string, len(s))
copy(c, s)
fmt.Println("cpy:", c)
```

আউটপুট:

```
cpy: [a b c d e f]
```

স্লাইসের সবচেয়ে গুরুত্বপূর্ন বৈশিষ্ট্য হলো এর স্লাইসিং অপারেটর। যেমন:

```go
l := s[2:5]
fmt.Println("sl1:", l)
```

আউটপুট:

```
sl1: [c d e]
```

এখানে আমরা `s` স্লাইসের ইনডক্স `2` (অর্থাৎ ৩য় আইটেম) থেকে শুরু করে ইনডেক্স `5` এর আগ পর্যন্ত, অর্থাৎ ইনডেক্স `4` বা ৫ম আইটেম পর্যন্ত `l` এ এ্যাসাইন করবো। এই অপারেশনের পর `l` হবে একটি নতুন স্লাইস যেটায় থাকবে `s[2]`, `s[3]` এবং `s[4]` এর ভ্যালু।

আমরা যদি প্রথম অংশ উহ্য রাখি সেক্ষেত্রে স্লাইসের একেবারে শুরু থেকে নতুন স্লাইস শুরু হবে:

```go
l = s[:5]
fmt.Println("sl2:", l)
```

এটার ভ্যালু হবে `s[0]` থেকে `s[4]` পর্যন্ত। আউটপুট:

```
sl2: [a b c d e]
```

মনে রাখতে হবে স্লাইসের প্রথম অংশ ইনক্লুসিভ, অর্থাৎ প্রথম অংশে যেই ইনডেক্স থাকে সেটি নতুন স্লাইসের শুরু, আর শেষ ভাগে যেই ইনডেক্স থাকে সেটা এক্সক্লুসিভ, অর্থাৎ সেটির আগ পর্যন্ত নতুন স্লাইসের অন্তর্গত হয়।

```go
l = s[2:]
fmt.Println("sl3:", l)
```

এটার আউটপুট:

```
sl3: [c d e f]
```

`make` ফাংশনটি ব্যবহার না করেও আমরা একই লাইনে স্লাইস ডিক্লেয়ার এবং ইনিশিয়ালাইজ করতে পারি এই শর্টহ্যান্ড সিনট্যাক্স ব্যবহার করে:

```go
t := []string{"g", "h", "i"}
fmt.Println("dcl:", t)
```

এটার আউটপুট:

```
dcl: [g h i]
```


# ম্যাপস

ম্যাপ হচ্ছে গো-এর এ্যাসোসিয়েটিভ ডাটা টাইপ। ম্যাপ এ আমরা একটি কি এর বিপরীতে একটি ভ্যালু স্টোর করি।

`make` ফাংশনটি ব্যবহার করে আমরা এভাবে একটি ম্যাপ তৈরি করতে পারি:

```go
m := make(map[string]int)
```

ম্যাপ এর ক্ষেত্রে `make` ফাংশনটির ফরম্যাটটি হলো - `map[ <কি-এর টাইপ> ] <ভ্যালু টাইপ>`

কি-ভ্যালু সেট করা খুবই সহজ:

```go
m["k1"] = 7
m["k2"] = 13
fmt.Println("map:", m)
```

আউটপুট:

```
map: map[k1:7 k2:13]
```

ভ্যালু রিট্রিভ করাও খুব জটিল নয়:

```go
v1, pres := m["k1"]
fmt.Println("v1: ", v1)
fmt.Println("pres: ", pres)
```

ভ্যালু রিট্রিভ করার সময় প্রথম রিটার্ন ভ্যালুটি হয় ঐ কি-এর ভ্যালু। দ্বিতীয় রিটার্ন ভ্যালুটি হয় বুলিয়ান। এটি নির্দেশ করে ঐ কি-টি ম্যাপে ছিলো কিনা। এটির মাধ্যমে জিরো ভ্যালুর ক্ষেত্রে সহজে বোঝা যায় ঐ কি-এর ভ্যালু কি সত্যিই জিরো ভ্যালু নাকি ঐ নামে কোন কি-ই ছিলো না ম্যাপে। উপরের কোডটির আউটপুট হবে:

```
v1:  7
pres:  true
```

ম্যাপ এর লেংথ জানতে আছে আমাদের পরিচিত `len` ফাংশনটি।

```go
fmt.Println("len:", len(m))
```

আউটপুট:

```
len: 2
```

কোন আইটেম ডিলিট করতে রয়েছে `delete` ফাংশনটি:

```go
delete(m, "k2")
fmt.Println("map:", m)
```

ডিলিট করার সময় ফাংশনে প্যারামিটার হিসেবে ম্যাপের নাম আর কোন আইটেম ডিলিট করতে হবে তার কি-টি দিতে হবে। এই কোডটির আউটপুট:

```
map: map[k1:7]
```


# রেঞ্জ

`range` ব্যবহার করে কোনো স্লাইস, ম্যাপ বা চ্যানেল iterate করা যায়। যখন স্লাইস iterate করার জন্য `range` ব্যবহার করা হয় তখন প্রতিটি iterate এর জন্য `range` দুটো ভ্যালু রিটার্ন করে: ইনডেক্স এবং ঐ ইনডেক্সের ভ্যালুর কপি। একটা উদাহরণ দেখা যাক:

```go
package main

import "fmt"

var doubles = []int{0, 2, 4, 6, 8, 10}

func main() {
    for i, v := range doubles {
        fmt.Println("Double of", i, "is", v)
    }
}
```

এখানে `doubles` অ্যারেটি আইটারেট করার জন্য `range` ব্যবহার করা হয়েছে। প্রতিটি iteration এ `i` আর `v` তে থাকবে যথাক্রমে ইনডেক্স আর ওই ইনডেক্সের ভ্যালুর কপি। প্রোগ্রাম রান করলে এই আউটপুট পাওয়া যাবে:

```
Double of 0 is 0
Double of 1 is 2
Double of 2 is 4
Double of 3 is 6
Double of 4 is 8
Double of 5 is 10
```

যদি ইনডেক্স বা ভ্যালুর দরকার না পড়ে তবে সেটা `_` ব্যবহার করে স্কিপ করা যায়। আবার শুধু ইনডেক্স চাইলে দ্বিতীয় ভ্যারিয়েবল লিখার প্রয়োজন পড়ে না। উদাহরণ দেখি:

```go
package main

import "fmt"

func main() {
    // ইন্টিজারের স্লাইস তৈরি করলাম
    doubles := make([]int, 6)

    // শুধু ইনডেক্স নিয়ে সেগুলোর সাথে দুই গুণ করছি
    for i := range doubles {
        doubles[i] = 2 * i
    }

    // এবার স্লাইসটির ভ্যালুগুলো দেখাচ্ছি, ইনডেক্স বাদ দেয়ার জন্য `_` ব্যবহার করছি
    for _, value := range doubles {
        fmt.Println(value)
    }
}
```

আউটপুট:

```
0
2
4
6
8
10
```


# ফাংশন

একটা ফাংশন কোনো আর্গুমেন্ট নিতে পারে নাও নিতে পারে। একটা নরমাল ফাংশনের উদাহরণ দেখি:

```go
package main

import "fmt"

func add(x int, y int) int {
    return x + y
}

func main() {
    fmt.Println(add(7, 6))
}
```

আউটপুট:\
‍\`\`\` 13

````
এখানে `add` ফাংশনটি দুটো আর্গুমেন্ট নেয়। `x` এবং `y` দুটোই ইন্টিজার। এটাকে সংক্ষেপে এভাবেও লিখা যায়:  

```go
func add(x, y int) int {
    return x + y
}
````

অর্থাৎ `(x int, y int)` কে `(x, y int)` এভাবে। আর রিটার্ন টাইপ এর পরে। এই ফাংশন `int` টাইপের ভ্যালু রিটার্ন করে। একটা ফাংশন মাল্টিপল ভ্যালু রিটার্ন করতে পারে। যেমন:

```go
func swap(x, y string) (string, string) {
    return y, x
}
```

অর্থাৎ এটা দুটো স্ট্রিং নিয়ে সোয়াপ করে তাদের রিটার্ন করবে। আবার named রিটার্ন ভ্যালু ব্যবহার করা যায়। এক্ষেত্রে শুধু কোন কোন ভ্যারিয়েবল রিটার্ন হবে সেটা বলে দিতে হয় রিটার্ন টাইপের জায়গায়, টাইপসহ। শুধু `return` স্টেটমেন্ট ব্যবাহর করতে হয় এক্ষেত্রে। এটাকে বলে `"naked" return`। উপরের `add` ফাংশনটি এভাবে লিখা যায়:

```go
func add(x, y int) (sum int) {
    sum = x + y
    return
}
```


# চলবে ...


