Go چطور اجرا میشود؟ مدلِ کامپایلسپساجرا
این نسخهی پیشنمایش عمومیه. برای نمره گرفتن، ذخیرهی پیشرفت و باز کردن درسهای بعدی ثبتنام کن.
ثبتنام رایگانورودخوش آمدی به دنیای Go
Go (که گاهی Golang هم صدایش میزنند) زبانی است که گوگل ساخت تا کدی سریع، خوانا و مطمئن بنویسیم. در این دوره از صفر شروع میکنیم و قدمبهقدم تا جایی پیش میرویم که بتوانی برنامههای واقعی بنویسی. اما قبل از نوشتن اولین خط کد، خوب است بدانی وقتی دکمهی اجرا را میزنی، پشتپرده دقیقاً چه اتفاقی میافتد.
دو دنیای متفاوت: مفسری در برابر کامپایلی
بعضی زبانها (مثل پایتون) مفسری هستند: یک برنامهی دیگر کد تو را خطبهخط میخواند و همان لحظه اجرا میکند. اما Go یک زبان کامپایلی است. این یعنی کدِ متنیِ تو قبل از اجرا یکبار بهطور کامل به زبان ماشین (دستورهایی که پردازنده مستقیم میفهمد) ترجمه میشود. به این مرحلهی ترجمه میگویند کامپایل (compile).
مسیر کار همیشه دو پله است:
کد منبع (main.go) → [کامپایل] → برنامهی اجرایی → [اجرا] → خروجی
یک نتیجهی مهم این مدل: کامپایلر قبل از اجرا به کل کدت نگاه میکند. اگر جایی اشتباه نحوی داشته باشی، برنامه اصلاً اجرا نمیشود و بهجایش یک خطای کامپایل میگیری. این سختگیری در ابتدا کمی اذیتکننده به نظر میرسد، اما در عمل جلوی خیلی از اشتباهها را همان اول میگیرد.
go run در برابر go build
برای اجرای کد Go از خط فرمان، دو دستور رایج وجود دارد:
go run main.go— کد را کامپایل میکند، بلافاصله اجرا میکند، و فایل اجراییِ موقت را بعدش دور میاندازد. برای آزمایشهای سریع عالی است؛ در این پلتفرم هم وقتی دکمهی اجرا را میزنی، رفتار از همین جنس است.go build— کد را کامپایل میکند و یک فایل اجراییِ ماندگار میسازد که بعداً میتوانی بارها بدون کامپایلِ دوباره اجرایش کنی. برای تحویلِ نهاییِ برنامه بهکار میآید.
در طول این دوره، تو فقط کد را مینویسی و دکمهی اجرا را میزنی؛ ما پشتصحنه آن را کامپایل و اجرا میکنیم. اما خوب است بدانی همان دو پله در حال انجام است.
محدودیتهای زمانی داور
داورِ این پلتفرم کد تو را روی موتوری به نام Piston با Go نسخهی 1.16.2 کامپایل و اجرا میکند. دو سقفِ زمانی وجود دارد که هیچوقت دردسرت نمیشود مگر کاری خیلی سنگین بکنی:
- کامپایل تا حدود ۱۰ ثانیه فرصت دارد (چون ترجمهی کد کمی زمان میبرد).
- اجرا تا حدود ۳ ثانیه فرصت دارد. پس از حلقههای بیپایان یا انتظارِ بیهوده پرهیز کن.
برای برنامههای این ماژول این سقفها عملاً نامحدود بهنظر میرسند؛ فقط خوب است بدانی وجود دارند.
چرا package main و func main اجباریاند؟
هر فایل Go با یک خط package شروع میشود که میگوید این فایل عضو کدام بسته (package) است. وقتی میخواهی یک برنامهی قابلاجرا بسازی (نه یک کتابخانه برای استفادهی دیگران)، باید بستهات دقیقاً main نام داشته باشد:
package main
و داخل این بسته باید تابعی به نام main باشد. Go وقتی برنامه را اجرا میکند، از همینجا شروع میکند — func main نقطهی شروعِ هر برنامهی اجراییِ Go است:
package main
import "fmt"
func main() {
fmt.Println("سلام دنیا")
}
این ساختار را خوب بهخاطر بسپار؛ هر برنامهای که در این ماژول مینویسی همین استخوانبندی را دارد: یک package main، یک یا چند import، و یک func main که کارِ اصلی داخلش انجام میشود.
import: آوردنِ ابزارهای آماده
برای چاپ در صفحه از بستهی استانداردِ fmt کمک میگیریم (نامش از format میآید). برای استفاده از هر بستهای، اول باید آن را import کنی. دو شکل نوشتن وجود دارد:
// شکل تکی: وقتی فقط یک بسته میخواهی
import "fmt"
// شکل بلوکی: وقتی چند بسته میخواهی، همه را داخل پرانتز میگذاری
import (
"fmt"
"strings"
)
یک قانون مهم: هر چیز import یا تعریفشده باید استفاده شود
Go سختگیریِ خاصی دارد که در ابتدا غافلگیرت میکند: اگر بستهای را import کنی اما در کد ازش استفاده نکنی، یا متغیری بسازی و هیچجا بهکارش نبری، کامپایل با خطا شکست میخورد. پیامش چیزی شبیه این است:
imported and not used: "strings"
declared but not used: x
فلسفهاش این است: کدِ بیاستفاده معمولاً نشانهی یک اشتباه یا فراموشی است، پس بهتر است همان اول جلویش گرفته شود تا کد همیشه تمیز بماند. پس اگر چنین خطایی دیدی، یا آن import/متغیر را بهکار ببر یا حذفش کن.
gofmt: تنها سبکِ رسمی
در خیلی از زبانها بحثهای طولانی درمیگیرد که «تورفتگی چند فاصله باشد؟»، «آکولاد کجا برود؟». Go این بحثها را یکبار برای همیشه تمام کرده است: ابزاری رسمی به نام gofmt وجود دارد که کد را به یک سبکِ استانداردِ واحد مرتب میکند (مثلاً تورفتگی با tab انجام میشود). همهی برنامهنویسهای Go از همین یک سبک استفاده میکنند، پس کدِ همه شبیه هم و خوانا است. در نمونههای این دوره هم همین قالببندی را میبینی.
مدلِ ارزیابی: OUTPUT_MATCH
حالا میرسیم به مهمترین نکته برای تمرینها. در این پلتفرم، داور برنامهی تو را اجرا میکند و خروجیِ آن (همان چیزی که چاپ میکنی) را با یک خروجیِ موردانتظار مقایسه میکند. به این روش OUTPUT_MATCH میگوییم: «خروجی باید مطابقت کند».
یعنی موفقیتِ تو در تمرین، به دقیق بودنِ خروجی بستگی دارد. اگر قرار است «سلام دنیا» چاپ شود اما تو «سلام دنیا!» چاپ کنی، یا یک خطِ اضافه بزنی، نتیجه فرق میکند. خبر خوب اینکه داور کمی بخشنده است: تفاوتهای کوچک مثل بزرگ/کوچک بودن حروف لاتین، یا فاصلهی دورِ علائم را نادیده میگیرد (در درس پایانیِ همین ماژول دقیقتر سراغ این موضوع میرویم). اما کلِ پیام و ترتیبِ خطها باید درست باشد.
پس از همین حالا یک عادتِ خوب را شروع کن: قبل از زدن دکمه، در ذهنت خروجیِ برنامهات را پیشبینی کن؛ این بهترین راه برای یادگیریِ واقعیِ کنترلِ خروجی است.
قدم بعدی
حالا که میدانی Go چطور کامپایل و اجرا میشود و ساختارِ یک برنامه چه شکلی است، در درس بعد اولین برنامهی واقعیمان را با دستهای خودت مینویسی: همان «سلام دنیا»ی معروف. بزن بریم!