آموزش زبان Go - بخش پنجم : انواع داده‌ای

زمانی که شما یک متغییر تعریف می‌کنید در واقع باید برای آن جایی در RAM کامپیوتر اشغال کنید مقدار این فضا و نوع چینش آن بسیار مهم است. مثلا اینکه شما چند بیت برای ذخیره مقداری احتیاج دارید. اینجاست که انواع داده‌ای در زبان‌های برنامه نویسی مهم می‌شوند. هر زبان برنامه نویسی به فراخور خودش میتواند انواع داده‌ای متفاوتی داشته باشد. در ادامه این مطلب نگاهی به انواع داده‌ای در زبان گو خواهیم انداخت و یاد خواهیم گرفت که چطور از آنها استفاده کنیم.

·۷ دقیقه برای خواندن
آموزش زبان Go - بخش پنجم : انواع داده‌ای

درک یک Error

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

var userName

userName = 'mhdi'
fmt.Println("userName")

اگر این کد را در ادیتور بنویسید قطعا متوجه خواهید شد که دارای Error است. اگر هم آن را اجرا کنید ( اگر یادتون رفته چطور می‌شه یک فایل رو اجرا کرد به این آدرس نگاه کنید) با چنین پیغامی مواجه خواهید شد.

❯ go run main.go
# command-line-arguments
.\main.go:11:15: syntax error: unexpected newline, expected type

یک عبارت جالب در این پیغام وجود دارد. syntax error یا به عبارتی خطای گرامری زمانی که شما گرامر زبان را رعایت نمی‌کنید با چنین خطایی رو به رو می‌شوید. اما چرا این خطا وجود دارد و چطور آن را رفع کنیم.

این متغییر از چه نوع هستش؟

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

var userName string

userName = 'mhdi'
fmt.Println("userName")

با اضافه کردن یک مقدار ساده string به کد مشکل حل می‌شود حالا کامپایلر می‌داند که با چه متغییری از چه نوعی طرف است و باید با آن چه رفتاری داشته باشد.

چه نوع متغییرهایی در زبان Go داریم؟

هدف من در اینجا فقط بیان کانسپت‌های پایه در این موضوع است البته این بخش در این مقاله تمام نمیشه و ما بعدا به شکل کاربردی با انواع دیگری در زبان گو آشنا خواهیم شد.

عدد صحیح ( Integer )

در کد زیر با پایه‌ای ترین مقدار شروع میکنیم عدد صحیح.

var x int = 4
var y int = -10

fmt.Printf("Type : %T, value: %v", x, x)
fmt.Printf("Type : %T, value: %v", y, y)

اگر آن را اجرا کنیم چنین خروجی‌ای خواهیم دید.

❯ go run main.go
Type : int, value: 4 
Type : int, value: -10

هر دو مقدار را از نوع integer نمایش می‌دهد. ولی این مقدار integer یعنی چقدر؟ اگر بخواهیم این مقدار را به شکل عددی بیان کنیم شما می‌توانید در یک متغییر از این نوع از عدد 9223372036854775808- تا 9223372036854775807 را ذخیره کنید البته این مقدار در سیستم‌های 64 بیتی است. خب این فضا برای ذخیره کردن یک عدد مثلا ۴ خیلی بزرگ است. دقیقا مثل اینکه شما یک دوچرخه را در فضای پارکینگ یک تریلی پارک کنید. برای حل این مشکل میتوان نوع متغییر int را کوچکتر در نظر گرفت.

var x int8 = 4

fmt.Printf("Type : %T, value: %v", x, x)

خروجی مورد انتظار در کد بالا چنین است.

❯ go run main.go
Type : int8, value: 4 

این یعنی برای ذخیره این عدد ما فقط ۸ بیت از فضای حافظه را اشغال کرده‌ایم در این فضا شما می‌توانید عددی از 128- تا 127 را ذخیره کنید که البته عدد ۴ در این بازه قرار دارد. نکته مهم اینکه این کمترین فضایی است که ما می‌توانیم داشته باشیم. اما یک سوال مهم آیا نباید در ۸ بیت بتوان تا ۲۵۵ ذخیره کرد!؟ این دقیقا فرق مقدار integers و unsigned integers است، در مقدار اینتیجر یک بیت به عنوان بیت علامت رزرو می‌شود که بتوان بازه اعداد را برای مقادیر مثبت و منفی گسترش داد اما در مقدار اینیجر بدون علامت آن یک بیت علامت دیگر وجود ندارد ولی دیگر مقدار منفی هم وجود نخواهد داشت. کد زیر نحوه تعریف مقادیر بدون علامت را نشان می‌دهد.

var y uint = 200

fmt.Printf("Type : %T, value: %v", y, y)

و خروجی کد بالا چنین خواهد شد.

❯ go run main.go     
Type : uint, value: 200

در مقدار uint شما می‌توانید از 0 تا 18446744073709551615 در سیستم‌های 64 بیتی ذخیره کنید. و برای uint8 میتوان از 0 تا 255 را ذخیره کرد.

عدد اعشاری ( Float )

در مقدار صحیح نمی‌توان عدد اعشاری ذخیره کرد. برای ذخیره اعداد اعشاری به نوع داده‌ای دیگری به نام float نیاز داریم. که میتوان از float64 یا float32 استفاده کرد. شما می‌توانید از 1.7e+308- تا 1.7e+308 را در float64 و از 3.4e+38- تا 3.4e+38 را در float32 ذخیره بکنید. طبیعتا برای تعریف این متغییر میتوان مثل کد زیر عمل کرد.

var x float = 12.75

fmt.Printf("Type : %T, value: %v", x, x)

خروجی هم به طبع قابل پیش بینی خواهد بود

❯ go run main.go     
Type : uint, value: 200

اگر در مقدار flaot بیشتر از توان ذخیره سازی مقدار بریزیم چه می‌شود

کد زیر را فرض بگیرید.

  var x float32= 3.4e+39  
  fmt.Println(x)

خب این بیشتر از مقدار قابل ذخیره سازی در float32 است و اگر آن را در vscode بنویسید می‌بینید که از همین الان عبارت cannot use 3.4e+39 (untyped float constant) as float32 value in variable declaration (overflows) ظاهر شده است. و حتی اگر کد را اجرا هم بکنیم.

❯ go run main.go
# command-line-arguments
.\main.go:27:18: cannot use 3.4e+39 (untyped float constant) as float32 value in variable declaration (overflows)

خروجی همچنان خطای overflow را نمایش خواهد داد این خطا زمانی رخ میدهد که شما بیشتر از توان یک نوع داده‌ای سعی می‌کنید در آن مقدار جای دهید

داده‌ی رشته‌ای ( String )

به طور کلی در زبان Go هر عبارتی که بین دو علامت " ( بخوانید دابل کوتیشن ) قرار بگیرد رشته یا string شناسایی می‌شود.

var txt1 string = "codepedia.top"
var txt2 string = "12"

fmt.Printf("Type : %T, value: %v\n", txt1, txt1)
fmt.Printf("Type : %T, value: %v", txt2, txt2)

و البته خروجی را هم به شکل زیر خواهید داشت.

❯ go run main.go     
Type : string, value: codepedia.top
Type : string, value: 12

صحیح یا غلط ( boolean )

در انتهای این لیست به مقدار درست و غلط خواهیم رسید. که حاوی یک نکته جالب است. شما در مقدار boolean به جز true یا false نمی‌توانید ذخیره کنید. یعنی کد زیر نمی‌تواند درست باشد.

var a bool = 12

در اینجا ما این خطا را خواهیم دید cannot use 12 (untyped int constant) as bool value in variable declaration از طرفی در ابتدای این مقاله دیدم که بعد از تعریف یک متغییر باید به آن مقدار داد. ولی نکته جالب اینکه مقدار boolean میتواند مقدار اولیه نداشته باشد یعنی میشود آن را چنین تعریف کرد.

var b bool

fmt.Printf("Type : %T, value: %v\n", b, b)

حالا اگر برای درک بهتر خروجی بگیریم.

❯ go run main.go
Type : bool, value: false

این به ما نشان می‌دهد که مقدار بولین در زبان Go به طور پیش فرض false است. بنابراین اگر قرار باشد مقدار آن را true در نظر بگیریم باید چنین کدی بنویسیم

var c bool = true

از نگاه خواننده ممکن است این موضوع تصور بشود که مقدار boolean بیشتر شبیه یک اتفاق مسخره است چیزی که همینطوری وجود دارد و البته کاربرد خاصی هم ندارد که باید بگم این تصور کاملا غلط است. در ادامه این دوره با هم با کاربردهای این نوع داده‌ای بیشتر آشنا خواهیم شد.

نتیجه گیری

برای ذخیره یک مقدار در حافظه RAM در زبان‌های برنامه نویسی باید یک متغییر تعریف کرد این متغییر مشخص میکنید که چه نوع داده‌ای و در چه حدی می‌توان ذخیره کرد. انتخاب صحیح نوع داده‌ای هم باعث کاهش میزان خطا در محاسبات و هم باعث بهبود کارایی برنامه شما خواهد شد.