الثلاثاء، 3 يناير 2012

تعلم لغة البرمجة Go بالعربي ( الدرس الثالث )

بسم الله الرحمن الرحيم
المتغيرات :


تستخدم المتغيرات لتخزين القيم و أسترجعها خلال تنفيذ البرنامج , و سوف نقوم في مثالنا الأول بتعديل برنامج Hello,World و تخزين عبارة الترحيب في متغير من نوع string :

المثال الأول
package main

import "fmt"

func main(){

var str1 string = "Hello,World or مرحبا بك"

fmt.Println(str1)

}




لاحظ السطر الثالث , حيث قمنا بتصريح المتغير str1 و أعطاءه القيمة النصية "مرحبا بك Hello,World or" و الطريقة العامة لتصريح متغير في لغة Go كالتالي :

var name type = value

  • var : الكلمة المفتاحية المستخدمة للتعريف المترجم بأننا نصرح عن متغير 
  • name : أسم المتغير , ويجب أن يبدأ بحرف من المجموعة (A-Z a-z) , كما يجب ان تنتبه أن لغة Go حساسة لحالة اﻷحرف .
  • type : نوع المتغير  و سوف أرفق بأنواع المتغيرات في نهاية الدرس .
  • value: بأمكانك تحديد قيمة للمتغير بعد علامة "=" و هذا أختياري في لغة Go عند أستخدام هذه الصيغة في التعريف عن متغير .

  • أنواع المتغيرات :
سوف أقسم أنواع المتغيرات حسب النوع و البيانات التي تستطيع تمثيلها :

1 .مجموعة الأعداد الصحيحة {....., -2 , -1 , 0 , 1 , 2 ,.....} :
  • int8   : يمثل هذا النوع الأرقام الصحيحة من المجال ( 127 إلى  128 ) .
  • int16 : الأرقام الصحيحة من المجال (32768 إلى 32767- ) .
  • int32 : الأرقام الصحيحة من المجال (2147483647 إلى 2147483648- ) .
  • int64 : الأرقام الصحيحة من المجال (9223372036854775807 إلى  9223372036854775808- )

2 . الأعداد الطبيعية الموجبة فقط  {0 , 1 , 2 , .....} :

  • uint8   : يمثل مجموعة الأرقام الموجبة من ( 0 إلى 255 ) .
  • uint16 : الأرقام الموجبة من ( 0 إلى 65535 ) .
  • uint32 : الأرقام الموجبة من ( 0 إلى 4294967295 ) .
  • uint64 : الأرقام الموجبة من ( 0 إلى 18446744073709551615) .
3 . الأرقام الحقيقة (الأعداد التي تحتوي على الفاصلة العشرية كـ"12.232" ) :

  • float32 : يمثل مجموعة الأعداد الحقيقة من (±3.4×1038 إلى ±1.18×10−38 )
  • float64 : يمثل مجموعة الأعداد الحقيقة من ( ±1.80×10308 إلى ±2.23×10–308 ) .
* لا يوجد النوع float في لغة Go




4 . الأعداد المعقدة (complex number )
هي أعداد تتكون من جزئين جزء حقيقي و الأخر أفتراضي كهذه الرقم 4+i4 , و يحتوي هذا النوع على :
  • complex32
  • complex128
* يرمز الرقم الذي يوجد بأسم المتغير على عدد البت "bits" التي يحتوي عليها هذا النوع .

في النهاية المتغيرات من النوع العددي سوف أتطرق لثلاثة أصناف :

1. int : يساوي عدد البت التي يحتويها على نوع المعالج ( المعالج من نوع 32 بت أو 64 بت ) , و لا يعتبره المترجم مساوي للنوع int32 أو int64 في حالة تساوي الـ"bits" , و يمثل الأعداد الصحيحة .
2. uint : كما في حالة الـ"int" , و يمثل الأعداد الطبيعة .
3. byte : أسم أخر للنوع uint8 , الذي تستطيع تمثيل حروف الأسكي به (ASCII) .

5. النصوص (string)

النصوص هي عبارة عن مصفوفة من البايتات (bits) تنتهي بالمحرف NULL أو "0/" , و تتميز لغة Go بأن المتغير string يدعم محارف UTF من يعني أنك تستطيع الكتابة بأي لغة .

6. المتغير المنطقي (bool)
المتغير المنطقي يحتمل قميتين فقط وهما صواب ( true ) خطأ ( flase ) .

المثال التالي يعرض عدد من أنواع المتغيرات الأساسية في لغة Go و طريقة التصريح :

المثال الثاني
package main

import "fmt"

func main() {

var a int =12

var b byte = 'c'

var c float32 = 12.423

var d bool = true

fmt.Println(a,b,c,d)

}
    تتميز لغة Go بأمكانية الأختصار , لذا سوف نعدل المثال الثاني كالتالي:

    package main

    import "fmt"

    func main() {

    var (

    int =12

    byte = 'c'

    c float32 = 12.423

    d bool = true 


    )

    fmt.Println(a,b,c,d)

    }


    حيث تخلصنا من تكرار الكلمة المفتاحية var بتعريف جميع المتغيرات بأستخدام var ثم و ضع المتغيرات بين " ( ) " القوسين , يجب أن أنبه أن كل متغير يجب أن يكون في سطر واحد .

    و الأن سوف أتطرق إلى خاصية التعرف الألي لنوع المتغير في لغة Go بهذا هذا التعديل للمثال الأول  :


    package
     main

    import "fmt"

    func main(){

    str1 := "Hello,World or مرحبا بك"

    fmt.Println(str1)

    }


    حيث كل ما يحتاجه المبرمج إليه المبرمج هو تعريف أسم المتغير يليه الأشارة " =: " ثم قيمة المتغير  , و لتقريب الفكرة سوف نعيد المثال الثاني بأستخدام "=:" :


    package
     main

    import "fmt"

    func main() {

    a :=12

    b := 'c'

    c := 12.423

    d := true 

    fmt.Println(a,b,c,d)

    }



    كما تستطيع أن  تختصر البرنامج بتعريف جميع المتغيرات في سطر واحد كما في هذا النص البرمجي :


    package
     main

    import "fmt"

    func main() {

    a,b,c,d :=12,'c',12.423,true

    fmt.Println(a,b,c,d)

    }







  • الثوابت :



  • الثوابت نوع من المتغيرات يتم تعريفه وقت ترجمة البرنامج , و في لغة Go من الممكن أن تكون نص "string" و أرقام "numbers" و قيم منطقية "Boolean" فقط , وتستطيع تعريف الثوابت بأستخدام الكلمة المفتاحية "const"  كالتالي :

    package main

    import "fmt"

    const (

           a=0

           b=1 )

    func main(){

    fmt.Println(b)

    }

    كما توفر لغة Go الخاصية iota لتشكيل سلاسل رقمية  :

    package main

    import "fmt"

    const (

         a=iota

         b=iota )

    func main(){

    fmt.Println(b)

    }

    عند هذا السطر سيفترض أن المترجم أن قيمة المتغير a تساوي الصفر :

           a=iota 

    ثم عند كتابة الكلمة iota في السطر الثاني سيتم زيادة المتغير التالي بقيمة واحد عن المتغير السابق,  وكل ما كتابة الكلمة البرمجية iota في سطر جديد سيتم زيادة القيمة بواحد .

    كما تستطيع أختصار النص البرمجي السابق كالتالي :

    package main

    import "fmt"

    const (

           a=iota

           b)

    func main(){

    fmt.Println(b)

    }


    تلاحظ أننا لم نكتب الكلمة البرمجية iota كقيمة للمتغير b , كما لم نحدد قيمة أخرى للمتغير , لذا سيقوم المترجم بزيادة قيمة المتغير b بواحد بشكل ألي .


    • العمليات الرياضية و المتغيرات :
    هذه قائمة بالعمليات الرياضية  الممكنة في لغة Go و الأنواع (types) الممكن إجراء العملية عليه :

    الأشارةالعمليةالأنواع
    +الجمعintegers, floats, complex , strings
    -الطرحintegers, floats, complex 
    *الضربintegers, floats, complex 
    /القسمةintegers, floats, complex 
    %باقي القسمةintegers
    &العملية المنطقية (AND)integers
    |العملية المنطقية (OR)integers
    ^العملية المنطقية (XOR)integers
    ^&العملية المنطقية (NOT AND)integers
    >>إزاحة البت (bits) بأتجاه اليسارintegers
    << إزاحة البت (bits) بأتجاه اليمينintegers


    • الأخطاء البرمجية في التعامل مع المتغيرات :
    1. التعريف عن متغير من دون أستخدامه في النص البرمجي :


    package
     main

    import "fmt"

    func main() {

    a :=12

    fmt.Println("Hello")
    }


    في هذا النص البرمجي البسيط صرحنا عن المتغير a فقط دون أستخدامه فعلياً و هذا يعتبر خطأ برمجي في لغة Go و لن يسمح لك المترجم بتحويل النص لبرنامج , و لكن في بعض الحالة تكون هنالك متغيرات غير مستخدمة من قبل المبرمج و لكن لا بد من التصريح عنها , مثل القيم المرجعة من دالة مثلا , و لذا قام المطورون للغة GO بأنشاء المتغير "_" الذي يتم تجاهله عند ترجمة البرنام كما في المثال التالي :


    package
     main

    import "fmt"

    func main() {

    _ :=12

    fmt.Println("Hello")
    }



    حاول ترجمة البرنامج التالي , لن يحصل هنا خطأ لأستخدام المتغير "_" .


    2.  إجراء العمليات الحسابية على نوعين مختلفين من المتغيرات :


    package main

    func main() {

    var a int=21

    var b int32=123

    var total int

    total = a + b

    }


    في هذا النص البرمجي حولنا جمع متغيران من نوع int32 و int و تخزين القيمة في متغير من نوع int , لم تستطيع ترجمة هذا النص البرمجي و سيظهر لك هذا الخطأ :

    abgoor@abgoor-Laptop:~$ 8g test.go

    test.go:7: invalid operation: a + b (mismatched types int32 and int)


    و يمكنك أستخدام خاصية التحويل بين الأنواع "Types" في لغة GO و هذا جدول يشرح بالمثال كيفية التحويل :

    من xb []bytexi []ints stringf float32i int
    إلى

    []byte
    x[]byte(s)
    []intx[]int(s)
    stringstring(xb)string(xi)x
    float32xfloat32(i)
    int int(f) x

    و الأن إلى بعض الملاحظات على هذا الجدول :

    1 . عند التحويل من float إلى int سيتم تجاهل الارقام التي تقع بعد الفاصلة العشرية .
    2 . الأماكن الفارغة في الجدول ترمز إلى عدم إمكانية التحويل .
    3. ما ينطبق على float32 ينطبق على float64 .
    4. القوسين في المتغيرات مثل "byte[]" ترمز لتعريف مصفوفة و في هذا الدرس ما يلزمك أن تعرف أنه لتعريف مصفوفة يجب  أن تستخدم التالي :

    a := []byte{1,2,3,4}

    5.بالنسبة لتحويل بين اﻷعداد الرقمية من نوع "Int" كانت صحيحة {....,-2,-1 , 0 , 1 ,2 , ...} , أو طبيعية { 0 , 1 , 2 , ......} ,  فبوضح المسألة  بهذا المثال :


    package main

    import "fmt"

    func main() {

    var a uint16 = 258

    var b uint8

    b =int8(a)

    fmt.Println(b)

    }

    ترى أننا صرحنا المتغير a من نوع uint16 بقيمة 258 ثم المتغير b من نوع uint8 , وحولنا قيمة المتغير a إلى النوع uint8 لكي يمكن أسنادها للمتغير b , المشكلة هنا تكمن في أن المتغيرات من نوع uint8 يمكن أن تكون قيمتها في المجال 0 إلى  255 فقط , طبعا في لغة C مثالاً قد يؤدي إلى خطأ overflow , و لكي تفهم ماذا سيحصل يجب أن تفهم طريقة تمثل البيانات في الذاكرة :

    0000 0001 0000 0010

    هكذا يكتب الرقم 258 بالأعداد الثنائية ( لغة الحاسب ) 

    ما ستقوم به لغة Go هو تجاهل البايت الملون بالأزرق , و أخذ قيمة البايت الملون باللون الأحمر و تخزينها في المتغير b , و ستصبح قيمة المتغير b تساوي 2 .

    طبعاً في أغلب الحالات هذا شيء غير مرغوب في برنامجك لذا يجب أن يكون التحويل بين المتغيرات الرقمية مراعياً لقيم القصوى الممكن تمثليها بواسطة المتغير .

    و الأن في نهاية هذا الدرس سوف نقوم بتعديل هذا المثال السابق   :


    package
     main

    func main() {

    var a int=21

    var b int32=123

    var total int

    total = int(a) + b

    }


    في حالة  وجود خطأ أو عندك تعديل فلا تتردد , و أن شاء الله بتتعلم في الدرس الرابع الوظائف "Function" في لغة GO .

    هناك تعليق واحد: