سعید فراهانی
سعید فراهانی
خواندن ۱۱ دقیقه·۱ سال پیش

متغیر ها در زبان گو (Go)

متغیر چیست
متغیر نام یک مکان حافظه است. آن مکان حافظه ممکن است مقداری از هر نوع را ذخیره کند. بنابراین هر متغیر دارای یک نوع است که اندازه و محدوده آن متغیر و همچنین عملیات تعریف شده روی آن متغیر را تعیین می کند.


قراردادهای نامگذاری متغیر ها در زبان برنامه نویسی Go

  • نام متغیر فقط می تواند با یک حرف یا زیرخط شروع شود.
  • بعد از آن می توان هر تعداد حروف، اعداد یا زیرخط را استفاده کرد
  • زبان Go به حروف بزرگ و کوچک حساس است، بنابراین با حروف بزرگ و کوچک متفاوت رفتار می شود.
  • نام متغیر نمی تواند نام هیچ کلمه کلیدی در زبان Go باشد
  • هیچ محدودیتی در طول نام متغیر وجود ندارد. اما توصیه می شود که نام متغیر طول بهینه را داشته باشید.


تعریف یک متغیر
در زبان Go متغیرها با استفاده از کلمه کلیدی var اعلان می شوند، اما روش های دیگری نیز برای اعلام یک متغیر وجود دارد که در ادامه این آموزش خواهیم دید. بیایید روش های مختلف اعلام یک متغیر را بررسی کنیم.


تعریف تک متغیری بدون مقدار اولیه
کد زیر روش اعلان یک متغیر منفرد بدون تخصیص مقدار اولیه است که شامل اول کلمه کلیدی var، دوم نام متغیر و سوم نوع متغیر است. همچنین توجه داشته باشید زمانی که مقدار ارائه نمی شود، متغیر با مقدار پیش فرض آن نوع که به عنوان مقدار صفر (zero) آن نوع نیز شناخته می شود مقداردهی اولیه می شود. در زبان Go مقدار پیش فرض یا مقدار صفر int عدد 0 است.

var <variable_name> <type>

package main import &quotfmt&quot func main() { var aaa int fmt.Println(aaa) }

خروجی: مقدار پیش فرض int را که 0 است را چاپ می کند

0


تعریف تک متغیری با مقدار اولیه

کد زیر فرمت یک اعلان متغیر منفرد با مقدار اولیه است. همه چیز مانند بالا است، تنها چیز اضافی این است که در پایان به متغیر مقدار اختصاص می دهیم

var <variable_name> <type> = <value>

مثال زیر را ببینید، یک متغیر به نام aaa از نوع int را اعلام می کند و به آن مقدار 8 می دهد.

package main import &quotfmt&quot func main() { var aaa int = 8 fmt.Println(aaa) }

خروجی:

8


تعریف چند متغیر بدون مقدار اولیه
در زیر فرمت اعلان چند متغیر بدون تخصیص مقدار اولیه قابل مشاهده است. لطفاً توجه داشته باشید که فقط متغیرهای یک نوع را می توان با هم اعلام کرد. توجه کنید که در تعریف متغیر، نوع در پایان می آید.

var <name1>, <name2>,….<nameN> <type>

مثال زیر را ببینید

package main import &quotfmt&quot func main() { var aaa, bbb int fmt.Println(aaa) fmt.Println(bbb) }

خروجی: مقدار پیش فرض یا صفر int را چاپ می کند که برای aaa و bbb صفر است

0 0


تعریف چند متغیر با مقدار اولیه
در قطعه کد زیر فرمت یک اعلان متغیر چندگانه با مقدار اولیه نمایش داده شده است. لطفاً توجه داشته باشید که فقط متغیرهای یک نوع را می توان با هم اعلام کرد.

var <name1>, <name2>, …..,<nameN> <type> = <value1>, <value2>, …..,<valueN>

نمونه کد زیر را ببینید. به متغیر aaa و bbb در یک اعلان به ترتیب مقدار 8 و 9 داده می شود.

package main import &quotfmt&quot func main() { var aaa, bbb int = 8, 9 fmt.Println(aaa) fmt.Println(bbb) }

خروجی:

8 9


تعریف متغیرهایی با انواع مختلف
در زیر فرمت اعلان چندین متغیر با انواع مختلف آورده شده است. در صورت نیاز مقادیر را می توان به متغیرها نسبت داد. متغیرهایی که مقدار برای آنها تخصیص داده نشده است، مقدار پیش فرض آن نوع را دریافت می کنند. در مثال زیر سه اعلان می بینیم.

package main import &quotfmt&quot func main() { var ( aaa int bbb int = 8 ccc string = &quota&quot ) fmt.Println(aaa) fmt.Println(bbb) fmt.Println(ccc) }

خروجی:

0 8 a


اعلان متغیر بدون نوع
متغیرها را نیز می توان بدون تعیین نوع آن اعلام کرد.

کامپایلر GO بر اساس مقدار تخصیص داده شده به متغیر، نوع آن را مشخص می کند. بنابراین اگر متغیر دارای مقدار اولیه باشد، می توان نوع را حذف کرد. این استنتاج نوع نیز نامیده می شود. در زیر فرمت چنین تعریفی آمده است

var <variable_name> = <value>

در زیر جدول استنتاج نوع برای انواع اساسی int، float، اعداد مختلط، رشته، بولی، کاراکترها آمده است. اساساً به این معنی است که اگر مقدار یک عدد صحیح باشد نوع متغیر استنباط شده int خواهد بود، اگر مقدار یک float باشد، نوع متغیر استنباط‌شده بر اساس جدول زیر float64 و غیره خواهد بود.

برای انواع دیگر مانند Array، Pointer، Structure و غیره، نوع Inference بر اساس مقدار اتفاق می افتد. بیایید یک مثال کاربردی از نکته بالا را ببینیم. توجه داشته باشید که نوع t به درستی به عنوان int استنباط می شود زیرا مقدار اختصاص داده شده به آن 123 است که int است. به طور مشابه نوع u نیز به درستی به عنوان رشته استنباط می شود زیرا مقدار اختصاص داده شده به آن یک رشته است.

همچنین توجه داشته باشید که نوع متغیر z به درستی به عنوان ساختار main.sample استنباط شده است

package main import &quotfmt&quot func main() { var t = 123 //Type Inferred will be int var u = &quotcircle&quot //Type Inferred will be string var v = 5.6 //Type Inferred will be float64 var w = true //Type Inferred will be bool var x = 'a' //Type Inferred will be rune var y = 3 + 5i //Type Inferred will be complex128 var z = sample{name: &quottest&quot} //Type Inferred will be main.Sample fmt.Printf(&quotType: %T Value: %v\n&quot, t, t) fmt.Printf(&quotType: %T Value: %v\n&quot, u, u) fmt.Printf(&quotType: %T Value: %v\n&quot, v, v) fmt.Printf(&quotType: %T Value: %v\n&quot, w, w) fmt.Printf(&quotType: %T Value: %v\n&quot, x, x) fmt.Printf(&quotType: %T Value: %v\n&quot, y, y) fmt.Printf(&quotType: %T Value: %v\n&quot, z, z) } type sample struct { name string }

خروجی:

Type: int Value: 123 Type: string Value: circle Type: float64 Value: 5.6 Type: bool Value: true Type: int32 Value: 97 Type: complex128 Value: (3+5i) Type: main.sample Value:


اعلان متغیر کوتاه
Go راه دیگری برای اعلان متغیرها ارائه می دهد که از عملگر := استفاده می کند. هنگامی که عملگر := استفاده می شود، هم کلمه کلیدی var و هم اطلاعات نوع را می توان حذف کرد. در زیر فرمت چنین اعلامیه ای آمده است

:=

استنتاج نوع همانطور که در بالا توضیح داده شد اتفاق می افتد. بیایید یک قطعه کد نمونه را بررسی کنیم:

package main import &quotfmt&quot func main() { t := 123 //Type Inferred will be int u := &quotcircle&quot //Type Inferred will be string v := 5.6 //Type Inferred will be float64 w := true //Type Inferred will be bool x := 'a' //Type Inferred will be rune y := 3 + 5i //Type Inferred will be complex128 z := sample{name: &quottest&quot} //Type Inferred will be main.Sample fmt.Printf(&quotType: %T Value: %v\n&quot, t, t) fmt.Printf(&quotType: %T Value: %v\n&quot, u, u) fmt.Printf(&quotType: %T Value: %v\n&quot, v, v) fmt.Printf(&quotType: %T Value: %v\n&quot, w, w) fmt.Printf(&quotType: %T Value: %v\n&quot, x, x) fmt.Printf(&quotType: %T Value: %v\n&quot, y, y) fmt.Printf(&quotType: %T Value: %v\n&quot, z, z) } type sample struct { name string }

خروجی

Type: int Value: 123 Type: string Value: circle Type: float64 Value: 5.6 Type: bool Value: true Type: int32 Value: 97 Type: complex128 Value: (3+5i) Type: main.sample Value:

چند نکته در مورد عملگر := قابل ذکر است

عملگر := فقط درون توابع قابل استفاده است. خارج از تابع مجاز نیست.
متغیری که یک بار با استفاده از := اعلام شده است را نمی توان با استفاده از عملگر := دوباره اعلام کرد. بنابراین عبارت زیر یک خطای کامپایلر را ایجاد می‌کند که “متغیر جدیدی در سمت چپ :=” وجود ندارد.

a := 8 a := 16

عملگر := همچنین می تواند برای اعلان چندین متغیر در یک خط استفاده شود. مثال زیر را ببینید

a,b := 1, 2

در صورت اعلان چندگانه، اگر حداقل یکی از متغیرهای سمت چپ جدید باشد، := می تواند دوباره برای یک متغیر خاص استفاده شود. مثال زیر را ببینید. توجه داشته باشید که b مجدداً با استفاده از := اعلام می شود که این تنها در صورتی امکان پذیر است که حداقل یکی از متغیرها جدید باشد که متغیر c در اینجا باشد. در این مورد به عنوان یک انتساب برای متغیر b عمل می کند

package main import &quotfmt&quot func main() { a, b := 1, 2 b, c := 3, 4 fmt.Println(a, b, c) }

خروجی:

1, 3, 4


نکات مهم
وجود یک متغیر استفاده نشده به عنوان یک خطای کامپایلر گزارش می شود. کامپایلر GO اجازه تعریف متغیر بدون استفاده ای را نمیدهد. این یک بهینه سازی در GO است. همانطور که در ادامه خواهیم دید، همین امر برای انواع ثابت (constant) نیز اعمال می شود. به عنوان مثال برنامه زیر یک خطای کامپایلر ایجاد می کند

package main func main() { //a declared but not used var a = 1 }

متغیری که در یک محدوده داخلی اعلام شده است بر روی متغیری با همان نام که در محدوده بیرونی معرفی شده است سایه می اندازد.

package main import &quotfmt&quot var a = 123 func main() { var a = 456 fmt.Println(a) }

خروجی:

456

بیان متغیر — در حالی که به متغیر اعلامی می توان یک عبارت یا یک تابع فراخوانی نیز اختصاص داد. مثال زیر را ببینید.
متغیر a با عبارت 5 +3 اعلام می شود
متغیر b با فراخوانی تابع math.Max(4, 5) اعلام می شود که نتیجه آن در زمان اجرا به b اختصاص داده می شود.

package main import ( &quotfmt&quot &quotmath&quot ) func main() { a := 5 + 3 b := math.Max(4, 5) fmt.Println(a) fmt.Println(b) }

خروجی:

8 5

زمانی که یک متغیر با یک نوع خاص مقداردهی اولیه شود، بعداً نمی‌توان به آن متغیر مقداری از نوع متفاوت نسبت داد. مثال زیر را ببینید

package main func main() { var aaa int = 1 aaa = &quotatest&quot bbb := 1 bbb = &quotbtest&quot }

خروجی:

cannot use &quotatest&quot (type untyped string) as type int in assignment cannot use &quotbtest&quot (type untyped string) as type int in assignment

به متغیر aaa یک نوع int اختصاص داده شده است، از این رو کامپایلر در اختصاص مقداری از نوع رشته به آن خطایی ایجاد می کند. برای متغیر bbb، نوع استنباط شده int است، از این رو با اختصاص مقداری از نوع رشته به آن، خطای کامپایلر را نیز ایجاد می کند.


محدوده یک متغیر (متغیر محلی و سراسری)
اعلان متغیر را می توان در سطح پکیج یا سطح تابع یا سطح بلوک انجام داد. محدوده یک متغیر محل دسترسی آن متغیر و همچنین عمر متغیر را مشخص می کند. متغیرهای زبان Go را می توان بر اساس دامنه به دو دسته تقسیم کرد

  • متغیر محلی
  • متغیر سراسری


متغیر محلی

  • متغیرهای محلی متغیرهایی هستند که در یک بلوک یا یک سطح تابع تعریف می شوند
  • نمونه ای از بلوک یک حلقه for یا یک حلقه محدوده و غیره است.
  • این متغیرها فقط از داخل بلوک یا تابع آنها قابل دسترسی هستند
  • این متغیرها فقط تا انتهای بلوک یا تابعی که در آن اعلان شده اند زنده هستند. پس از آن، آنها از حافظه پاک میشوند.


مثال زیر را ببینید

  • متغیر i بعد از حلقه for در دسترس نیست
  • به طور مشابه aaa خارج از تابعی که در آن اعلان شده است در دسترس نیست.

بنابراین برنامه زیر خطای کامپایلر را افزایش می دهد

undefined: i undefined: aaa

کد:

package main import &quotfmt&quot func main() { var aaa = &quottest&quot fmt.Println(aaa) for i := 0; i < 3; i++ { fmt.Println(i) } fmt.Println(i) } func testLocal() { fmt.Println(aaa) }


متغیر سراسری

  • یک متغیر در صورتی که در بالای یک فایل خارج از محدوده هر تابع یا بلوکی اعلان شود، درون یک پکیج به صورت سراسری خواهد بود.
  • اگر نام این متغیر با حروف کوچک شروع شود، می‌توان از داخل پکیجی که این تعریف متغیر را در خود دارد به آن دسترسی داشت.
  • اگر نام متغیر با یک حرف بزرگ مشخص شود، می‌توان از پکیجی خارج از پکیج که اعلام شده است، به آن دسترسی پیدا کرد.
  • متغیرهای سراسری در طول عمر یک برنامه در دسترس هستند


به عنوان مثال در زیر متغیر برنامه aaa یک متغیر سراسری در سراسر پکیج اصلی خواهد بود. در هر عملکردی در پکیج اصلی موجود خواهد بود. توجه داشته باشید که نام متغیر خارج از پکیج اصلی در دسترس نخواهد بود زیرا نام آن با حروف کوچک شروع می شود.

package main import &quotfmt&quot var aaa = &quottest&quot func main() { testGlobal() } func testGlobal() { fmt.Println(aaa) }

خروجی:

test

نتیجه
آنچه بیان شد همه چیز در مورد متغیرها در زبان Go است. امیدواریم این مقاله را دوست داشته باشید. لطفا بازخورد یا بهبود یا اشتباهات را در نظرات به اشتراک بگذارید.


-----------------------------------

توجه: در بخشی از متن ترجمه شده به جهت خوانایی بیشتر، به نحوی که در مفهوم مطالب تغییری ایجاد نشود تغییراتی ایجاد شده است.

منبع:

https://golangbyexample.com/variables-in-golang-complete-guide/

زبان برنامه نویسیزبان برنامه نویسی goآموزش زبان برنامه نویسی go
شاید از این پست‌ها خوشتان بیاید