Ko'pchilik tillar o'z vositalarini yillar davomida uchinchi tomonlardan to'playdi: bu yerda build vositasi, u yerda test ishga tushirgichi, hamjamiyatning yarmi kelishgan formatlovchi. Go bularning barchasi bilan birinchi kunidanoq, yagona go buyrug'i ostida chiqdi, va aynan shu qaror Go loyihalarining bir kod bazasidan ikkinchisiga o'tganda shu qadar bir xil tuyulishining katta sababidir. Ushbu bobda siz kuniga o'nlab marta yozadigan buyruqlar ko'rib chiqiladi: go run, go build va go test, hamda vosita allaqachon biladigan javob kerak bo'lganda ishlatiladigan go doc va go help.
go run dasturni kompilyatsiya qiladi va darhol ishga tushiradi, ikkilik faylni esa keyin o'chirib tashlaydi:
go run main.go
Ichkarida bu baribir to'liq kompilyatsiya — Goda interpretator rejimi yo'q — ammo kompilyator shu qadar tezki, ko'pchilik dasturlar uchun bu aylanma yo'l bir zumda o'tayotgandek tuyuladi. Agar paketingiz bir nechta faylga yoyilgan bo'lsa, ularni sanang yoki niqobdan foydalaning:
go run *.go
go run main.go utils.go
go run ni alohida fayllarga emas, paketga ham yo'naltirishingiz mumkin, va loyiha o'sgach, odatda shunisi yaxshiroq odat:
go run ./cmd/server
Kodni qayta-qayta o'zgartirib sinayotganingizda — o'zgarishni tekshirish, bir martalik skript ishga tushirish, qoralama faylda tajriba qilish — go run ga murojaat qiling, siz haqiqatan yetkazib bera oladigan yoki birovga bera oladigan artefakt kerak bo'lganda esa go build ga o'ting.
Farq shunchaki kelishuvda emas:
go running ikkilik fayli vaqtinchalik papkada yashaydi va buyruq tugagach yo'qoladi, shuning uchun uni deploy qilib bo'lmaydi; bundan tashqari,go runni takror-takror chaqirish har safar ozgina qo'shimcha vaqt sarflaydi, ko'p marta ishga tushiriladigan dastur uchun esa bittago buildbundan qutqaradi.
go build paketni bajariladigan faylga kompilyatsiya qiladi (agar u main paketi bo'lsa) yoki toza kompilyatsiya bo'layotganini tekshiradi (agar bo'lmasa — kutubxona paketlari chiqish fayli hosil qilmaydi, faqat build keshiga yozuv qo'shadi):
go build
main paketi bor papkada argumentsiz ishga tushirilsa, u modul (yoki papka) nomi bilan atalgan bajariladigan faylni o'sha yerning o'ziga tashlab ketadi: Linux va macOSda ./main, Windows'da main.exe. Ko'pincha esa siz aniq bir paketni build qilib, chiqish yo'lini o'zingiz tanlaysiz:
go build ./cmd/server
go build -o bin/myapp ./cmd/server
./... — "shu papka va uning ostidagi hamma narsa" degan pattern, va u asboblar to'plami bo'ylab doimo uchraydi, faqat build bilan emas:
go build ./...
Bir nechta bayroqni yoddan bilish foydali. -v kompilyatsiya qilinayotgan paketlar nomini chiqaradi, bu sekin build chindan ish qilayotganini tasdiqlash uchun foydali. -race ma'lumotlar poygasi (data race) detektorini qo'shib kompilyatsiya qiladi: u xotiraga murojaatlarni kuzatadi va bir xil xotiraga sinxronizatsiyasiz, bir vaqtda murojaat qilinganini ma'lum bir ishlash tezligi evaziga xabar qiladi — CI'da bebaho, garchi -race bilan yig'ilgan ikkilik faylni ishlab chiqarishga chiqarmasangiz ham. -tags build teglarini yoqadi va turli muhitlar uchun turli kodni kompilyatsiya qilish imkonini beradi (bu mavzuni 51-bob kod generatsiyasi bilan birga yoritadi). -ldflags esa bog'lovchiga (linker) qiymat uzatadi, ko'pincha build paytida ikkilik faylga versiya satri yoki commit xeshini muhrlash uchun:
go build -ldflags "-X main.version=1.2.3" -o bin/myapp
go build -ldflags="-s -w" -o bin/myapp # ikkilik fayl kichikroq bo'lishi uchun debug ma'lumotini olib tashlaydi
Kross-kompilyatsiya ichiga o'rnatilgan va har bir maqsad uchun alohida asboblar to'plamini talab qilmaydi — siz shunchaki ikkita muhit o'zgaruvchisini o'rnatasiz:
GOOS=linux GOARCH=amd64 go build -o myapp-linux
GOOS=windows GOARCH=amd64 go build -o myapp.exe
GOOS=darwin GOARCH=arm64 go build -o myapp-mac-arm64
go tool dist list qo'llab-quvvatlanadigan har bir GOOS/GOARCH juftligini ko'rsatadi.
Bu Goning buyruq qatori vositalari va infratuzilma dasturlari orasida shu qadar mashhur bo'lib ketishining asosiy sabablaridan biridir: CI/CD yoki reliz jarayoni (pipeline) uchun Mac noutbukidan Linux binar faylini yig'ish — shunchaki ikkita muhit o'zgaruvchisini ko'rsatish bilan hal bo'ladi. Hech qanday og'ir Docker obrazi yoki qo'shimcha kross-kompilyator o'rnatish shart emas.
Testlash tilga testing paketi va go test buyrug'i orqali o'rnatilgan — asosiy ishlar uchun tanlaydigan yoki o'rnatadigan alohida framework yo'q:
go test # joriy paketni testlash
go test ./... # joriy papka va uning ostidagi hamma narsani testlash
Test fayli o'zi testlaydigan kod yonida yashaydi, nomi _test.go bilan tugaydi, test funksiyalari esa Test bilan boshlanadi va *testing.T ni qabul qiladi:
// math_test.go
package math
import "testing"
func TestAdd(t *testing.T) {
if got := Add(2, 3); got != 5 {
t.Errorf("Add(2, 3) = %d; want 5", got)
}
}
go test bu fayllarni faqat testlash paytida kompilyatsiya qiladi — ular go build dan chetlashtiriladi — mos keladigan har bir Test* funksiyasini ishga tushiradi va o'tdi/o'tmadi xulosasini beradi:
PASS
ok github.com/user/project 0.123s
--- FAIL: TestAdd (0.00s)
math_test.go:8: Add(2, 3) = 6; want 5
FAIL
FAIL github.com/user/project 0.123s
Bilish foydali bo'lgan bayroqlar: har bir test bo'yicha batafsil chiqish uchun -v, nom patterniga mos keladigan testlarnigina ishga tushirish uchun -run TestAdd (paketda yuzlab test bo'lib, siz bitta muvaffaqiyatsizlikni tekshirayotganingizda foydali), qamrovni o'lchash uchun -cover va -coverprofile=coverage.out, testlarni ma'lumotlar poygasi detektori ostida ishga tushirish uchun -race, benchmark funksiyalarini ishga tushirish uchun -bench=., hamda osilib qolgan test butun jarayon to'xtatilgunga qadar qancha ishlashi mumkinligini chegaralash uchun -timeout. 36-bobdan 39-bobgacha jadvalga asoslangan testlar, subtestlar, fuzzing va integratsion testlash chuqur ko'rib chiqiladi — bu bob esa shunchaki test to'plamini ishga tushirishga yetadigan darajada asosiy ko'nikmalarni beradi.
Go hujjatlarni manba kodingizdagi izohlardan hosil qiladi, go doc esa ularni brauzersiz terminalda o'qish imkonini beradi:
go doc fmt # paket haqida umumiy ma'lumot
go doc fmt.Println # bitta funksiya
go doc net/http.Server # bitta tip
go doc net/http.Server.ListenAndServe # bitta metod
go doc -all fmt # eksport qilingan hamma narsa
go doc -http=:6060 xuddi shu hujjatlarni http://localhost:6060 manzilida lokal veb-sahifa sifatida uzatadi, bu butun paket arxitekturasini qulay ko'zdan kechirish uchun ayni muddao. 53-bobda chiroyli o'qiladigan hujjat izohlarini yozish va ochiq pkg.go.dev saytining shu qoidalarga qanday tayanishi yoritiladi.
go help — vositaning o'z ma'lumotnomasi:
go help # barcha buyruqlar ro'yxati
go help build # bitta buyruq bo'yicha yordam
go help modules # kengroq mavzu bo'yicha yordam
Bayroqning aniq nomini unutganingizda —
go help <buyruq>internetdan qidirishdan ancha tezroq va u siz o'rnatgan Go versiyasiga aniq mos keladi.
Yana bir nechta ichki buyruq kundalik ishni to'ldiradi, ularning har biri o'z bobida to'liq ko'rib chiqiladi: go mod bog'liqliklarni boshqaradi (init, tidy, download, vendor — 7-bob), go get bog'liqlik qo'shadi yoki yangilaydi, go install dasturni kompilyatsiya qilib, ikkilik faylni joriy papkaga emas, $GOBIN (yoki $GOPATH/bin) ga joylaydi — Goda yozilgan buyruq qatori vositalarini shunday o'rnatasiz, go fmt va go vet esa formatlash va statik tahlil bilan shug'ullanadi (6-bob).
Ko'p ishlatiladigan odatiy ketma-ketliklar:
go build && ./myapp # build qilib, so'ng ishga tushirish
go test -cover ./... # hamma narsani qamrov bilan testlash
go fmt ./... && go vet ./... # formatlab, so'ng shubhali xatolarni tekshirish
Bularning barchasi qulay va izchil. Buyruqlar soni kam, nomlari nima qilishini aniq aytib turadi, bayroqlar esa chalkashliksiz, qisqa va barqaror ro'yxatdan iborat.
go build,go testvago vetmuharriringiz hamda CI/CD tizimingizga ulangach, vositalar to'plami haqida ortiqcha bosh qotirmaysiz, bu esa e'tiboringizni eng asosiy narsaga — sifatli kod yozishga qaratish imkonini beradi.
Keyingi bobda o'sha vositalarning ikkitasini — go fmt va go vet ni, hamda go doc vositasi o'qiy oladigan qilib hujjat izohlarini to'g'ri yozish qoidalarini yaqinroq ko'rib chiqamiz.