لغة Go بالأمثلة: الشرائح (slice)

الشرائح نوع بيانات مهم في Go، وتوفر وسيلة أقوى للتعامل مع التسلسلات مقارنة بالمصفوفات.

package main
import (
    "fmt"
    "slices"
)
func main() {

بخلاف المصفوفات، يتحدد نوع الشريحة بنوع العناصر التي تحتويها فقط، لا بعددها. تساوي الشريحة غير المهيأة nil ويكون طولها 0.

    var s []string
    fmt.Println("uninit:", s, s == nil, len(s) == 0)

لإنشاء شريحة بطول غير صفري، استخدم الدالة المدمجة make. ننشئ هنا شريحة من عناصر string طولها 3 وتأخذ عناصرها قيمتها الصفرية في البداية. تساوي سعة الشريحة الجديدة طولها افتراضيًا؛ وإذا عرفنا مسبقًا أن الشريحة ستنمو، فيمكننا تمرير السعة صراحةً كوسيط إضافي إلى make.

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

يمكننا إسناد العناصر واسترجاعها كما في المصفوفات.

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

تعيد len طول الشريحة كما هو متوقع.

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

إلى جانب هذه العمليات الأساسية، تدعم الشرائح عدة عمليات أخرى تجعلها أغنى من المصفوفات. إحداها الدالة المدمجة append، التي تعيد شريحة تحتوي على قيمة جديدة واحدة أو أكثر. لاحظ أن علينا استخدام القيمة المعادة من append لأننا قد نحصل على شريحة جديدة.

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

يمكن أيضًا نسخ الشرائح باستخدام copy. ننشئ هنا شريحة فارغة c لها طول s نفسه، ثم ننسخ من s إلى c.

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

تدعم الشرائح عامل إنشاء شريحة فرعية بالصيغة slice[low:high]. فمثلًا، نحصل هنا على شريحة من العناصر s[2] وs[3] وs[4].

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

تنشئ هذه الصيغة شريحة حتى s[5] دون تضمينه.

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

وتنشئ هذه شريحة بدءًا من s[2] مع تضمينه.

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

يمكننا أيضًا التصريح عن متغير لشريحة وتهيئته في سطر واحد.

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

تحتوي الحزمة slices على عدد من الدوال المساعدة المفيدة للشرائح.

    t2 := []string{"g", "h", "i"}
    if slices.Equal(t, t2) {
        fmt.Println("t == t2")
    }

يمكن تركيب الشرائح في هياكل بيانات متعددة الأبعاد. ويمكن أن تختلف أطوال الشرائح الداخلية، بخلاف المصفوفات متعددة الأبعاد.

    twoD := make([][]int, 3)
    for i := range 3 {
        innerLen := i + 1
        twoD[i] = make([]int, innerLen)
        for j := range innerLen {
            twoD[i][j] = i + j
        }
    }
    fmt.Println("2d: ", twoD)
}

لاحظ أن الشرائح، رغم اختلافها عن المصفوفات في النوع، تُعرض بطريقة مشابهة عند استخدام fmt.Println.

$ go run slices.go
uninit: [] true true
emp: [  ] len: 3 cap: 3
set: [a b c]
get: c
len: 3
apd: [a b c d e f]
cpy: [a b c d e f]
sl1: [c d e]
sl2: [a b c d e]
sl3: [c d e f]
dcl: [g h i]
t == t2
2d:  [[0] [1 2] [2 3 4]]

اقرأ هذه التدوينة المميزة من فريق Go لمزيد من التفاصيل حول تصميم الشرائح وتنفيذها في Go.

بعد أن تعرفنا على المصفوفات والشرائح، سننتقل إلى هيكل بيانات مدمجة أساسية أخرى في Go، وهي الخرائط.

المثال التالي: .