خلاصه مختصر مفید GoLang (پارت اول)

اگه پارت اول رو قبلاً مطالعه کردین میتونین پارت دوم رو اینجا مطالعه کنین


اگه بخوایم خلاصه ببینیم زبان برنامه نویسی Go چیه به آدرس ویکیپدیای فارسی این صفحه استناد میکنیم:

این زبان در نوامبر ۲۰۰۹ معرفی شد و در حال حاضر در چند سامانهٔ اجرایی گوگل استفاده می‌شود. مترجم گو از لینوکس، مک او اس، ویندوز و انواع سیستم‌های عامل بی‌اس‌دی مانند FreeBSD پشتیبانی می‌کند. از لحاظ معماری پردازنده نیز، معماری ایکس۸۶، معماری ایکس۶۴، معماری آرم و معماری POWER که مخصوص به شرکت آی‌بی‌ام است، توسط مترجم گو پشتیبانی می‌شوند

به زبون خودمونی، گو رو بر و بچه های گوگل توسعه دادن، روی اکثر سیستم عاملای مرسوم قابل اجراس و زبون سطح بالاییه. شرکتایی مثل Google و Uber و Netflix و eBay و Apple و SoundCloud و Twitter و ... از این زبون استفاده کردن. فکر میکنم اسم این شرکتا واسه نشون دادن قدرت این زبون کافیه ولی واسه اطمینان بیشتر میشه به این پروژه ها هم اشاره کرد که جفتشون از گو استفاده کردن و هردو متن باز هم هستن: Docker ، kubernetes

خب خیلی سریع بریم سراغ این که ببینیم زبون گو چه شکلیه (البته قبلش اشاره کنم که توی این آموزش خیلی سریع و خلاصه فقط میخوایم سینتکس و قابلیتای این زبون رو بررسی کنیم)

تعریف متغیر

var card string = &quotHello world&quot

برای تعریف میگم یه var یا همون variable داریم به اسم card که از نوع string هست و مقراشم برابر Hello world گذاشتیم. زبون go این اجازرو میده که همین خط رو بتونیم به شکل زیر و خلاصه تر بنویسیم:

card := &quotHello world&quot

این ساختار دقیقاً شبیه حالت قبلی عمل میکنه. زبون go از این variable ها پشتیبانی میکنه.

نمایش پیغام

این زبون بصورت پیشفرض از پکیج هایی استفاده میکنه (که شدیداً توصی میکنم سر صبری نگاهی بهشون بندازین) و fmt یکی از اونهاست. ساده ترین حالت نمایش پیغام هم بصورت زیر:

fmt.Println("a message")

تعریف type

تقریبا همچی توی زبون go یه type هست و ما میتونیم تایپ های خودمون رو هم ایجاد کنیم. مثلا وقتی بنویسیم

type arrayType []string

یعنی هر جایی که بنویسیم arrayType منظورمون []string هست

آرایه

حالا این []string چی هست؟ میخوایم یه مجموعه داشته باشیم.

var a [2]string

یعنی یه آرایه دارم که دو تا عضو داره و اسمشم a هست. آرایه توی زبون go تعداد عناصر ثابتی داره و محدودم هست. یه ساختار دیگه ای داره به اسم slice که شبیه همون آرایه تعریف میشه با کمی تغییر

s := []int{2, 3, 5, 7, 11, 13}

و خودش یسری امکانات دیگه هم میده بهمون مثل اینکه بتونیم یه قسمتی از یه آرایه رو با ایندکس هاش جدا کنیم:

s = s[2:4]

یعنی از دومی تا چهارمی (شامل دومی ولی تا قبل از چهارمی)

s = s[:n]

یعنی از اول تا قبل از عنصر n

s = s[4:]

یعنی از عنصر چهارم (شامل خود چهارمی) تا آخر لیست

ساختار map

اگه بخوایم ساختار key value داشته باشیم میتونیم از map استفاده کنیم:

colors := map[string]string{
		&quotred&quot:   &quot#ff0000&quot,
		&quotblue&quot:  &quot#0000ff&quot,
		&quotgreen&quot: &quot#00ff00&quot,
	}

یا بصورت زیر تعریف کنیم:

var colors map[string]string
colors := make(map[string]string)

این make چیز باحالیه، هرچیزی بخواین تعریف کنین (یا بهتره بگیم اکثر چیزارو) میتونین با این ساختار توی زبون برنامه نویسی گو تعریف کنین.

به این شکل هم میتونیم عنصری رو فراخونی یا حذفش کنیم:

colors[10] = &quot#ffffff&quot
delete(colors, 10)

بد نیس نگاهی هم به این عکس بندازیم:

Maps VS Struct in GoLang
Maps VS Struct in GoLang

ساختار یا Struct

زبون برنامه نویسی Go چیزی به اسم کلاس نداره. میشه توش Struct بصورت زیر تعریف کرد:

type person struct {
    name string
    age  int
}

یچیزیه شبیه کلاس توی زبونای برنامه نویسی شی گرا. به این صورت

p := person{&quotBob&quot, 20}

یا به این صورت

p := person{name: &quotAlice&quot, age: 30}

هم میشه یه person جدید تعریف کرد.

تابع

شبیه خیلی از زبونای برنامه نویسی توابع بصورت زیر (و با کلمه کلیدی func) تعریف میشن

func funName(inputs) output{
 	...
 }

میتونه ورودی خروجی داشته باشه یا نداشته باشه یا چندتا داشته باشه:

func funName(inputs) outputKind{
        ...
 	return ...
 }

 func funName() outputKind{
        ...
 	return ...
 }

همونطور که گفتیم میتونه چندتا خروجی هم داشته باشی که به این صورت استفاده میشه:

func funName(arg int) (int, string){  	
        return arg ,&quottest&quot  
}    

a,t := funName(10)

اگه یجایی _ بذاریم یعنی اون متغیر رو نیاز نداریم که ازش استفاده کنیم و اسمی براش در نظر نمیگیریم:

_ , t := funName(10)

اینترفیس

اینترفیس رو هم موقع تعریف شبیه خیلی از زبونا برنامه نویسی به شکل زیر پیاده سازی میکنیم:

type bot interface {
	getGreeting() string
}

اما موقع استفاده ازش اینجوری نیست که توی هر structی که تعریف کردیم بگیم باید ازن اینترفیس رو پیاده سازی بکنه. بلکه بصورت زیر عمل میکنیم:

type englishBot struct{}
type spanishBot struct{}

func (englishBot) getGreeting() string {
	return &quotHello&quot
}

func (spanishBot) getGreeting() string {
	return &quothola&quot
}

و وقتی یه تابع تو مایه های زیر داشته باشیم:

func printGreeting(b bot) {
	fmt.Println(b.getGreeting())
}

موقعی که داریم صدا میزنیمش چک میکنه ببینه که اون اینترفیس bot که توی ورودی تابع میخواد بگیره رو، چیزی که به عنوان ورودی بهش دادیم پیاده سازیش کرده یا نه.

تابع مختص یه نوع (reciever)

یکی دیگه از ویژگی های زبون go اینه که میتونیم برای یسری نوع (type)های خاص تابعی بنویسیم که فقط برای خودش باشه (شبیه موقعی که داریم توی یه زبون شی گرا داخل کلاسش تابع پیاده سازی میکنیم). به شکل زیر عمل میکنیم:

func (d tType) toString() string{
...
}

یعنی هر نوعی که tType باشه میتونه بصورت

tType.toString()

این تابع رو صدا بزنه.

خطاها

این زبون چیزی به اسم exception handling به اون شکلی که توی زبونایی مثه جاوا شاید دیده باشین نداره. بجاش هر تابعی که بخواد خطایی داشته باشه یه نوع error برمیگردونه. اگر هم بخوایم خودمون میتونیم error های خودمون رو تعریف کنیم و توی توابعمون اونها رو استفاده کنیم.
برای مثال به این شکل میتونیم یه ساختار ارور جدید تعریف کنیم:
type argError struct {
    arg  int
    prob string
}

به این صورت هم میتونیم تابعی تعریف کنیم که در صورت نیاز خطایی برگردونه:

func f2(arg int) (int, error) {
    if arg == 29 {
        // In this case we use `&argError` syntax to build
        // a new struct, supplying values for the two
        // fields `arg` and `prob`.
        return -1, &argError{arg, &quotcan't work with it&quot}
    }
    return arg + 3, nil
}

و به این شکل هم میتونیم ازشون استفاده کنیم:

_ , e := f2(42)
if ae, ok := e.(*argError); ok {
    fmt.Println(ae.arg)
    fmt.Println(ae.prob)
}

اوه چرا یهو انقد عجیب قریب شد، مگه نه؟ بذارین ببنیم ساختارش چه شکلیه

کلمه ی if اول و ok آخر خط دوم رو نگاه کنین، بین اونا اومدن این رو گذاشتیم:

ae, ok := e.(*argError);

مفهومشم اینه که ae و ok خروجی هامونن (که اینجا ae همون arg و ok همون prob داخل ساختار argError هستن. e هم که خودش argError هست دیگه)

حالا اون شرط یعنی اگه نوشته ای داخل ok بود مفهومش اینه که خطایی اتفاق افتاده و بریم واسه نشون دادن پیغام، در غیر این صورت (nil بودن ok) مفهومش اینه که خطایی نداشتیم و وارد حلقه نمیشیم.

شروط

یه مدل شرط رو توی مثال قبل دیدیم، اما بصورت کلی شروط به این صورت قابل پیاده سازین:

   a = false
   b = true
   if ( a && b ) {
      fmt.Printf(&quotLine 1 - Condition is true\n&quot )
   } else {
      fmt.Printf(&quotLine 1 - Condition is not true\n&quot )
   }
   if ( !(a && b) ) {
      fmt.Printf(&quotLine 2 - Condition is true\n&quot )
   }

حلقه

ساده ترین مدل به این شکله:

for true  {
    fmt.Printf(&quotThis loop will run forever.\n&quot)
}
و میتونیم بجای true یه متغیر تعریف کنیم که دونه دونه کم بشه تا صفر:
i:=10
for i>0  {
     fmt.Printf(i);
     i = i-1
}

یا اینکه به صورت مرسوم توی بقیه زبونا به این شکل تعریف بشه:

for i := 0; i < 3; i++ {
    fmt.Println(from, &quot:&quot, i)
}


پارت دوم رو میتونید اینجا مطالعه کنین


منتشر شده در ویرگول توسط محمد قدسیان https://virgool.io/@mohammad.ghodsian

https://virgool.io/@mohammad.ghodsian/%D8%AE%D9%84%D8%A7%D8%B5%D9%87-%D9%85%D8%AE%D8%AA%D8%B5%D8%B1-%D9%85%D9%81%DB%8C%D8%AF-golang-%D9%BE%D8%A7%D8%B1%D8%AA-%D8%A7%D9%88%D9%84-lvge8wj8n4xd