Dynamic Slices in Go

List Topics
February 17, 2025
No Comments
5 min read

In Go, slices are more flexible than arrays because their size is not fixed. A slice can dynamically grow and shrink, making them a powerful feature in Go. Slices are built on top of arrays, and they allow you to work with a subset of an array or dynamically resize the collection as needed.

Step-by-Step Explanation:

1️⃣ Declaring a Slice

Unlike arrays, slices do not require you to specify a length at the time of declaration. You only need to specify the element type.

🔹 Example:

Go
package main

import "fmt"

func main() {
    // Declaring a slice
    var slice []int

    fmt.Println(slice)  // Print the empty slice
}

🔹 Output:

Bash
[]

👉 In this example, slice is declared but not initialized with any values. It is an empty slice.

2️⃣ Initializing a Slice

You can initialize a slice with values by providing the values within curly braces, just like you would with arrays.

🔹 Example:

Go
package main

import "fmt"

func main() {
    // Initializing a slice with values
    slice := []int{10, 20, 30}

    fmt.Println(slice)  // Print the initialized slice
}

🔹 Output:

Bash
[10 20 30]

👉 Here, the slice is initialized with the values 10, 20, and 30.

3️⃣ Appending to a Slice

One of the key features of slices is that you can dynamically add elements to them using the built-in append() function. The slice will automatically resize as necessary to accommodate the new elements.

🔹 Example:

Go
package main

import "fmt"

func main() {
    // Initialize a slice
    slice := []int{1, 2, 3}

    // Append elements to the slice
    slice = append(slice, 4, 5)

    fmt.Println(slice)  // Print the modified slice
}

🔹 Output:

Bash
[1 2 3 4 5]

👉 In this example, we append 4 and 5 to the slice, and it dynamically grows to accommodate the new elements.

4️⃣ Capacity of a Slice

A slice in Go has two important properties: length (the number of elements in the slice) and capacity (the total number of elements the slice can hold without reallocating). The capacity can increase when elements are appended beyond the current capacity.

🔹 Example:

Go
package main

import "fmt"

func main() {
    slice := make([]int, 0, 5)  // Create a slice with initial length 0 and capacity 5

    fmt.Println("Initial slice:", slice)
    fmt.Println("Initial length:", len(slice))
    fmt.Println("Initial capacity:", cap(slice))

    slice = append(slice, 1, 2, 3)

    fmt.Println("Updated slice:", slice)
    fmt.Println("Updated length:", len(slice))
    fmt.Println("Updated capacity:", cap(slice))
}

🔹 Output:

Bash
Initial slice: []
Initial length: 0
Initial capacity: 5
Updated slice: [1 2 3]
Updated length: 3
Updated capacity: 5

👉 In this example, we create a slice with an initial capacity of 5 but no elements. After appending, the length increases to 3, but the capacity remains 5 because the slice has not exceeded its initial capacity.

5️⃣ Growing a Slice Beyond its Capacity

When a slice exceeds its capacity, Go automatically allocates a new, larger array, copies the existing elements, and appends the new elements to the new array. This process involves reallocating memory.

🔹 Example:

Go
package main

import "fmt"

func main() {
    slice := make([]int, 0, 3)  // Create a slice with initial capacity of 3

    fmt.Println("Initial slice:", slice)
    fmt.Println("Initial capacity:", cap(slice))

    // Append more elements than the initial capacity
    slice = append(slice, 1, 2, 3, 4)

    fmt.Println("Updated slice:", slice)
    fmt.Println("Updated capacity:", cap(slice))
}

🔹 Output:

Bash
Initial slice: []
Initial capacity: 3
Updated slice: [1 2 3 4]
Updated capacity: 6

👉 Here, the slice starts with a capacity of 3. After appending more elements than its capacity, the capacity automatically grows to 6, and the slice is resized.

6️⃣ Slicing a Slice

Slices are also flexible in terms of slicing another slice. You can create a sub-slice from an existing slice.

🔹 Example:

Go
package main

import "fmt"

func main() {
    slice := []int{10, 20, 30, 40, 50}

    // Create a sub-slice from index 1 to 3
    subSlice := slice[1:4]

    fmt.Println(subSlice)  // Print the sub-slice
}

🔹 Output:

Bash
[20 30 40]

👉 Here, we create a sub-slice from index 1 to 3, resulting in the slice [20, 30, 40].

Summary:

  • Slices in Go are more flexible than arrays because their size can change during runtime.
  • You can append elements to a slice, and Go will automatically resize it as necessary.
  • A slice has both length (the number of elements) and capacity (the space allocated for elements).
  • When a slice exceeds its capacity, Go automatically reallocates a larger array to hold the elements.
  • Sub-slicing is also possible, allowing you to create smaller slices from an existing slice.

ডাইনামিক স্লাইসেস (Dynamic Slices) ইন গো

গো-তে স্লাইস হচ্ছে এমন একটি ডেটা স্ট্রাকচার, যার আকার ফিক্সড নয়। এটি ডাইনামিকভাবে বাড়ানো বা ছোটানো যায়। স্লাইসগুলো অ্যারেগুলোর ওপর ভিত্তি করে তৈরি, তবে এগুলোর আকার পরিবর্তন করা সম্ভব, যার ফলে এগুলো আরো বেশি নমনীয় এবং শক্তিশালী।

ধাপে ধাপে ব্যাখ্যা:

1️⃣ একটি স্লাইস ঘোষণা করা

গো-তে স্লাইস ঘোষণা করতে আপনাকে আকার নির্ধারণ করতে হয় না। শুধুমাত্র উপাদানটির ধরনের উল্লেখ করতে হয়।

🔹 উদাহরণ:

Go
package main

import "fmt"

func main() {
    // স্লাইস ঘোষণা করা
    var slice []int

    fmt.Println(slice)  // খালি স্লাইস প্রিন্ট করা
}

🔹 আউটপুট:

Bash
[]

👉 এখানে slice স্লাইসটি ঘোষণা করা হয়েছে, কিন্তু কোন মান দেওয়া হয়নি, এটি একটি খালি স্লাইস।

2️⃣ একটি স্লাইস ইনিশিয়ালাইজ করা

গো-তে, স্লাইসকে শুরুতেই মান দিয়ে ইনিশিয়ালাইজ করা যায়।

🔹 উদাহরণ:

Go
package main

import "fmt"

func main() {
    // স্লাইস ইনিশিয়ালাইজ করা
    slice := []int{10, 20, 30}

    fmt.Println(slice)  // ইনিশিয়ালাইজড স্লাইস প্রিন্ট করা
}

🔹 আউটপুট:

Bash
[10 20 30]

👉 এখানে, স্লাইসটি 10, 20, এবং 30 মান দিয়ে ইনিশিয়ালাইজ করা হয়েছে।

3️⃣ একটি স্লাইসে অ্যাপেন্ড (Add) করা

গো-তে স্লাইসে নতুন উপাদান যোগ করতে append() ফাংশন ব্যবহার করা হয়। এই ফাংশনটি স্লাইসটিকে স্বয়ংক্রিয়ভাবে বড় করে দেয় যদি তার বর্তমান ক্ষমতা (capacity) শেষ হয়ে যায়।

🔹 উদাহরণ:

Go
package main

import "fmt"

func main() {
    // একটি স্লাইস ইনিশিয়ালাইজ করা
    slice := []int{1, 2, 3}

    // স্লাইসে উপাদান যোগ করা
    slice = append(slice, 4, 5)

    fmt.Println(slice)  // স্লাইসটি প্রিন্ট করা
}

🔹 আউটপুট:

Bash
[1 2 3 4 5]

👉 এখানে, 4 এবং 5 স্লাইসে অ্যাপেন্ড করা হয়েছে, এবং স্লাইসটি ডাইনামিকভাবে বড় হয়েছে।

4️⃣ স্লাইসের ক্ষমতা (Capacity)

গো-তে একটি স্লাইসের দুটি গুরুত্বপূর্ণ বৈশিষ্ট্য থাকে: দৈর্ঘ্য (length) এবং ক্ষমতা (capacity)। ক্ষমতা হল স্লাইসটি কতটা জায়গা ধারণ করতে পারে যখন পুনঃঅবস্থান (reallocation) না করা হয়।

🔹 উদাহরণ:

Go
package main

import "fmt"

func main() {
    slice := make([]int, 0, 5)  // স্লাইস তৈরি করা যার প্রাথমিক দৈর্ঘ্য 0 এবং ক্ষমতা 5

    fmt.Println("প্রাথমিক স্লাইস:", slice)
    fmt.Println("প্রাথমিক দৈর্ঘ্য:", len(slice))
    fmt.Println("প্রাথমিক ক্ষমতা:", cap(slice))

    slice = append(slice, 1, 2, 3)

    fmt.Println("আপডেটেড স্লাইস:", slice)
    fmt.Println("আপডেটেড দৈর্ঘ্য:", len(slice))
    fmt.Println("আপডেটেড ক্ষমতা:", cap(slice))
}

🔹 আউটপুট:

Bash
প্রাথমিক স্লাইস: []
প্রাথমিক দৈর্ঘ্য: 0
প্রাথমিক ক্ষমতা: 5
আপডেটেড স্লাইস: [1 2 3]
আপডেটেড দৈর্ঘ্য: 3
আপডেটেড ক্ষমতা: 5

👉 এখানে, স্লাইসটির প্রাথমিক ক্ষমতা ছিল 5, এবং এটি 3টি উপাদান অ্যাপেন্ড করার পরেও ক্ষমতা 5-তেই রয়ে গেছে।

5️⃣ ক্ষমতার সীমা অতিক্রম করলে স্লাইস বৃদ্ধি

যখন স্লাইস তার প্রাথমিক ক্ষমতা অতিক্রম করে, গো স্বয়ংক্রিয়ভাবে নতুন বড় অ্যারে বরাদ্দ করে এবং পুরনো উপাদানগুলো নতুন অ্যারেতে কপি করে।

🔹 উদাহরণ:

Go
package main

import "fmt"

func main() {
    slice := make([]int, 0, 3)  // স্লাইস তৈরি করা যার প্রাথমিক ক্ষমতা 3

    fmt.Println("প্রাথমিক স্লাইস:", slice)
    fmt.Println("প্রাথমিক ক্ষমতা:", cap(slice))

    // স্লাইসে বেশি উপাদান অ্যাপেন্ড করা
    slice = append(slice, 1, 2, 3, 4)

    fmt.Println("আপডেটেড স্লাইস:", slice)
    fmt.Println("আপডেটেড ক্ষমতা:", cap(slice))
}

🔹 আউটপুট:

Bash
প্রাথমিক স্লাইস: []
প্রাথমিক ক্ষমতা: 3
আপডেটেড স্লাইস: [1 2 3 4]
আপডেটেড ক্ষমতা: 6

👉 এখানে, স্লাইসটির ক্ষমতা ছিল 3, কিন্তু উপাদান বেশি অ্যাপেন্ড করার পর এটি স্বয়ংক্রিয়ভাবে ক্ষমতা বাড়িয়ে 6 হয়ে গেছে।

6️⃣ স্লাইস থেকে স্লাইস তৈরি করা (Sub-Slicing)

গো-তে আপনি একটি স্লাইস থেকে অন্য স্লাইস তৈরি করতে পারেন। এটি আপনাকে একটি বড় স্লাইস থেকে ছোট অংশ বের করার সুবিধা দেয়।

🔹 উদাহরণ:

Go
package main

import "fmt"

func main() {
    slice := []int{10, 20, 30, 40, 50}

    // স্লাইস থেকে সাব-স্লাইস তৈরি করা
    subSlice := slice[1:4]

    fmt.Println(subSlice)  // সাব-স্লাইস প্রিন্ট করা
}

🔹 আউটপুট:

Bash
[20 30 40]

👉 এখানে, স্লাইসের ইনডেক্স 1 থেকে 3 পর্যন্ত সাব-স্লাইস তৈরি করা হয়েছে, যার ফলস্বরূপ [20, 30, 40] পাওয়া গেছে।

সারাংশ:

  • স্লাইস গো-তে ডাইনামিক ডেটা স্ট্রাকচার, যার আকার চলাকালীন সময়ে পরিবর্তিত হতে পারে।
  • append() ফাংশন ব্যবহার করে স্লাইসে উপাদান অ্যাপেন্ড করা যায়, এবং এটি স্বয়ংক্রিয়ভাবে স্লাইসের আকার বৃদ্ধি করে।
  • স্লাইসের দৈর্ঘ্য (length) এবং ক্ষমতা (capacity) থাকে, যেখানে ক্ষমতা সীমা অতিক্রম করলে গো স্বয়ংক্রিয়ভাবে নতুন অ্যারে বরাদ্দ করে।
  • সাব-স্লাইস তৈরি করা যায় একটি স্লাইস থেকে, যা উপকারী হতে পারে।

©2025 Linux Bangla | Developed & Maintaind by Linux Bangla.