الأساسيات

المصفوفات Arrays

المصفوفات Arrays

المصفوفة Array هي مجموعة Collection من العناصر التي تنتمي لنفس نوع البيانات Data type.
على سبيل المثال, مجموعة الأعداد الصحيحة 5,8,9,79,76 تُشكل مصفوفة .

ملاحظة: في لغة غو, لايجوز أن نُشكل مصفوفة من قيم ذات أنواع بيانات مختلفة مثل أن نشكل مصفوفة من الأعداد الصحيحة والنصوص Strings, هذا ممنوع في لغة غو.

– إنشاء مصفوفة

المصفوفة تنتمي لنوع البيانات n[T]           0, حيث n يمثل عدد العناصر في المصفوفة, وT يمثل نوع بيانات العناصر.
ويوجد عدة طرق لإنشاء المصفوفات في لغة غو

مثال

package main

import (  
    "fmt"
)


func main() {  

//int array with length 3
    var a [3]int 
    fmt.Println(a)
}

في السطر التاسع,var a [3]int, يعني إنشاء مصفوفة تُدعى a وتتألف من 3 عناصر من نوع int .
وفي هذه الحالة, جميع عناصر المصفوفة a تأخذ القيمة الصفرية (أو الفارغة اذا كانت مصفوفة نصوص).
وعند تنفيذ المثال أعلاه تكون النتيجة

[0 0 0]

وفهرس المصفوفة Index يبدأ التعداد من الصفر.

لنجرب أن نعيّن بعض القيم للمصفوفة أعلاه.

package main

import (  
    "fmt"
)


func main() {  
    var a [3]int 
    a[0] = 12 
    a[1] = 78
    a[2] = 50
    fmt.Println(a)
}

والنتيجة ستكون

[12 78 50]

– إنشاء مصفوفة بالطريقة المختصرة Array Shorthand

package main 

import (  
    "fmt"
)

func main() {  
    a := [3]int{12, 78, 50}
    fmt.Println(a)
}

ونتيجة تنفيذ المثال ستكون

[12 78 50]

وعند استخدام الطريقة المختصرة في انشاء مصفوفة, فليس من الضروري أن نعيّن قيم جميع عناصر المصفوفة

فهذا مثال على انشاء مصفوفة ذات 3 عناصر بالطريقة المختصرة مع تعيين قيمة أول عنصر فيها ..

package main

import (  
    "fmt"
)

func main() {  
    a := [3]int{12} 
    fmt.Println(a)
}

والنتيجة

[12 0 0]

ويمكننا أن نتجاهل “عدد عناصر المصفوفة” وأن نستبدله بثلاث نقاط وأن نترك المجمّع Compiler أن يقوم بعدّ العناصر بنفسه

package main

import (  
    "fmt"
)

func main() {  
    a := [...]int{12, 78, 50}
    fmt.Println(a)
}

وفي المصفوفات Arrays يُعتبر عدد العناصر كجزء من نوع البيانات, أي أنه ثابت لايمكن إضافة عناصر أو إنقاص عناصر لاحقاً, عدد عناصر المصفوفة دائماً ثابت,
أما اذا كنت بحاجة لتعديل عدد عناصر المصفوفة فيوجد حل بديل وهو “ الشرائح Slices” وسيتم شرحه في الدرس القادم.

مثال على عملية خاطئة على المصفوفات في لغة غو

package main

func main() {  
    a := [3]int{5, 78, 8}
    var b [5]int
    b = a 
}

تنفيذ هذا البرنامج سينتج عنه خطأ بسبب السطر السادس وسبب ذلك هو أن السطر الرابع يحتوي على مصفوفة من نوع [3]int والسطر الخامس يحتوي على مصفوفة من نوع بيانات مختلف وهو [5]int
أي أنه يوجد لدينا مصفوفتان من نوع بيانات مختلفان, ولذلك لايمكن إجراء أي عمليات حسابية بينهما !

المصفوفات هي قيّم وليست مراجع Arrays are value types NOT REFERENCES

المصفوفات في لغة غو هي من أنواع القيّم values وليست من أنواع المراجع أو المؤشرات references.
هذا يعني أنه اذا كان لدينا مصفوفة معينة لمتغير ما, ثم قمنا بتعيينها لمتغير آخر, فهنا يتم أخذ “نسخة” من المصفوفة واعتبارها وكأنها مصفوفة جديدة ذات عنوان ذاكرة Memory Adress مختلف
أي أننا اذا عدلنا على المصفوفة المعينة بالمتغير الجديد فالتعديلات ستكون محصورة حصراً بالمتغير الجديد ولن تؤثر على المصفوفة المعينة بالمتغير القديم/السابق.

مثال

package main

import "fmt"

func main() {  
    a := [...]string{"USA", "China", "India", "Germany", "France"}
    b := a 
    b[0] = "Singapore"
    fmt.Println("a is ", a)
    fmt.Println("b is ", b) 
}

والنتيجة ستكون

a is [USA China India Germany France]  
b is [Singapore China India Germany France]

وكذلك الأمر ينطبق ان كنا نمرر المصفوفة كأنها باراميتر parameter في دالة ما.

package main

import "fmt"

func changeLocal(num [5]int) {  
    num[0] = 55
    fmt.Println("inside function ", num)

}
func main() {  
    num := [...]int{5, 6, 7, 8, 8}
    fmt.Println("before passing to function ", num)
    changeLocal(num)
    fmt.Println("after passing to function ", num)
}

والنتيجة

before passing to function  [5 6 7 8 8]  
inside function  [55 6 7 8 8]  
after passing to function  [5 6 7 8 8]

– طول مصفوفة Length

package main

import "fmt"

func main() {  
    a := [...]float64{67.7, 89.8, 21, 78}
    fmt.Println("length of a is",len(a))

}

والنتيجة

length of a is 4

الدالة len تساعدنا بمعرفة عدد عناصر مصفوفة ما.

– التكرار عبر المصفوفة بواسطة range

يمكننا استخدام حلقة for للتكرار iteration عبر المصفوفات بلغة غو

مثال

package main

import "fmt"

func main() {  
    a := [...]float64{67.7, 89.8, 21, 78}
    for i := 0; i 

والناتج سيكون

0 th element of a is 67.70  
1 th element of a is 89.80  
2 th element of a is 21.00  
3 th element of a is 78.00

وهذا صحيح وممكن وجيد, ولكن لغة غو توفر طريقة أفضل ومحكمة أكثر للتكرار عبر المصفوفة باستخدام صيغة range لحلقة for, حيث يُعاد لنا “فهرس العنصر Index” و “قيمة العنصر Value”.
والان لنحاول اعادة كتابة المثال السابق باستخدام range.

package main

import "fmt"

func main() {  
    a := [...]float64{67.7, 89.8, 21, 78}
    sum := float64(0)
    for i, v := range a {
        fmt.Printf("%d the element of a is %.2f\n", i, v)
        sum += v
    }
    fmt.Println("\nsum of all elements of a",sum)
}

والناتج سيكون

0 the element of a is 67.70  
1 the element of a is 89.80  
2 the element of a is 21.00  
3 the element of a is 78.00

sum of all elements of a 256.5

في السطر الثامن, for i, v := range a, حيث أن موضع المتغير الأول يأخذ فهرس العنصر (i), وفي موضع المتغير الثاني يكون قيمة هذا العنصر (v).

ويمكننا اهمال فهرس العنصر أو قيمة العنصر من خلال استخدام المعرّف الفارغ Blank Identifier _

مثال

//ignores index
for _, v := range a {   
}

مصفوفات متعددة الأبعاد Multidimensional arrays

مثال

package main

import (  
    "fmt"
)

func printarray(a [3][2]string) {  
    for _, v1 := range a {
        for _, v2 := range v1 {
            fmt.Printf("%s ", v2)
        }
        fmt.Printf("\n")
    }
}

func main() {  
    a := [3][2]string{
        {"lion", "tiger"},
        {"cat", "dog"},
        {"pigeon", "peacock"}, 
    }
    printarray(a)
    var b [3][2]string
    b[0][0] = "apple"
    b[0][1] = "samsung"
    b[1][0] = "microsoft"
    b[1][1] = "google"
    b[2][0] = "AT&T"
    b[2][1] = "T-Mobile"
    fmt.Printf("\n")
    printarray(b)
}

في المثال السابق, في السطر السابع عشر, تم الاعلان عن انشاء مصفوفة متعددة الابعاد معينة بالمتغير a باستخدام الطريقة المختصرة Shorthand.

ملاحظة: الفاصلة العشرية في نهاية السطر العشرين ضرورية وذلك لأن المجمّع يضيف تلقائياً فاصلة منقوطة (;) في نهاية السطر ان لم يجد فاصلة عشرية, سيتم شرح هذا الموضوع في دروس قادمة.

ودالة printarray في السطر السابع تستخدم حلقتي for بصيغة range لتطبع محتويات المصفوفة ثنائية الأبعاد.
وناتج المثال اعلاه سيكون

lion tiger  
cat dog  
pigeon peacock 

apple samsung  
microsoft google  
AT&T T-Mobile

انتهى الى هنا درس المصفوفات, في الدرس القادم سنتعرف على نوع آخر من المصفوفات يُدعى الشرائح Slices.

ملاحظة: يمكنك تشغيل أكواد وأمثلة لغة غو من خلال GoLang Playground أو GoPlay.Space .

نبذة عن الكاتب

Firas M. Darwish

Software Engineer, PHP/Laravel, C#, GoLang, founder of ArGoLang.com & others ..

شاركنا رأيك :)