16-bo‘lim
Paketlar va modullar
Paket nomlari, katta harf orqali ko'rinuvchanlik, import yo'llari va taxalluslar, go.mod va go.sum, internal papkasi hamda init funksiyasi.
Ushbu bo‘lim mundarijasi
Loyiha o'sgani sari kodni bo'lish kerak bo'ladi. Go da buning ikki darajasi bor: paket va modul.
Ikki daraja #
| Tushuncha | Nima |
|---|---|
| Paket | Bitta papkadagi fayllar to'plami |
| Modul | Birga tarqatiladigan paketlar to'plami |
Modul - bu go.mod fayli turgan papka va uning ichidagi hamma
narsa.
Katta harf - ko'rinuvchanlik #
Go da public va private kalit so'zlari yo'q. Buning o'rniga
nomning birinchi harfi hal qiladi.
package hisob
// Qosh - tashqaridan ko'rinadi (katta harf)
func Qosh(a, b int) int {
return a + b
}
// tekshir - faqat shu paket ichida (kichik harf)
func tekshir(son int) bool {
return son >= 0
}
type Talaba struct {
Ism string // ko'rinadi
ball int // ko'rinmaydi
}
Bu qoida hamma narsaga taalluqli: funksiya, tur, o'zgaruvchi, doimiy va struktura maydonlari.
Java da public, private, protected, package-private bor -
to'rtta daraja va ularni yozish kerak.
Go da ikkita daraja bor va ular nomning o'zida ko'rinadi. Funksiyani o'qiyotganingizda, uning tashqariga chiqishini bilish uchun hech qayerga qarash kerak emas.
Bu 11-bo'limdagi JSON teglari bilan ham bog'liq: json paketi
boshqa paketda turgani uchun, u faqat katta harfli maydonlarni
ko'ra oladi.
Import qilish #
package main
import (
"fmt"
"strings"
"misol.uz/maktab/hisob"
)
func main() {
fmt.Println(hisob.Qosh(2, 3))
fmt.Println(strings.ToUpper("salom"))
}
Import yo'li - papkaning to'liq yo'li, paket nomi emas. Lekin kodda paket nomi ishlatiladi.
Odatda ular bir xil bo'ladi, shuning uchun chalkashlik kam.
gofmt importlarni ikki guruhga ajratadi: standart kutubxona
yuqorida, qolganlari pastda.
Taxalluslar #
import (
"math/rand"
krand "crypto/rand"
_ "github.com/lib/pq"
. "fmt"
)
| Shakl | Ma'nosi |
|---|---|
krand "crypto/rand" | Boshqa nom berish |
_ "..." | Faqat init uchun import |
. "fmt" | Nomsiz ishlatish |
. "fmt" yozsangiz, Println ni to'g'ridan-to'g'ri yozish
mumkin bo'ladi - fmt. siz.
Bu qulaydek tuyuladi, lekin kodni o'qishni buzadi: Println
qayerdan kelganini bilib bo'lmaydi. Katta faylda bu jiddiy
muammo.
Amalda uni deyarli hech kim ishlatmaydi. _ esa haqiqatan kerak
bo'ladi - ma'lumotlar bazasi drayverlari o'zini shu yo'l bilan
ro'yxatdan o'tkazadi.
go.mod fayli #
module misol.uz/maktab
go 1.24
require (
github.com/google/uuid v1.6.0
golang.org/x/text v0.14.0 // indirect
)
| Qator | Ma'nosi |
|---|---|
module | Modul nomi (import yo'lining boshi) |
go | Til versiyasi |
require | Kerakli bog'liqliklar |
// indirect | Bevosita ishlatilmaydi, bog'liqlikning bog'liqligi |
Bog'liqlik qo'shish uchun uni kodda import qilib, keyin shu buyruqni berasiz:
go mod tidy
go mod tidy kodni o'qib chiqadi: yetishmaydiganini yuklaydi,
ortiqchasini olib tashlaydi.
go.sum nima uchun kerak #
go.mod yonida go.sum fayli paydo bo'ladi. Uning ichida har bir
bog'liqlikning kriptografik barmoq izi saqlanadi.
Keyingi safar kod yuklanganda, Go uning izini qayta hisoblab,
go.sum bilan solishtiradi. Agar mos kelmasa, u qurishni
to'xtatadi.
Bu nimadan himoya qiladi: kimdir omborga kirib, eski versiyaning kodini jimgina o'zgartirib qo'ysa, siz buni darhol bilasiz.
Shuning uchun go.sum ni ham albatta git ga qo'shing.
internal papkasi #
internal deb nomlangan papka maxsus: uning ichidagi paketlarni
faqat shu modulning o'zi import qila oladi.
misol.uz/maktab/internal/baza <- faqat maktab ichidan
misol.uz/maktab/hisob <- hamma joydan
Boshqa modul internal ichidagi narsani import qilmoqchi bo'lsa,
kompilyator rad etadi.
Bu nima uchun foydali: kutubxona yozayotganda ba'zi kod tashqariga
chiqmasligi kerak, lekin u bir nechta ichki paketga bo'lingan
bo'lishi mumkin. Katta harf bu yerda yordam bermaydi - internal
esa aynan shu muammoni hal qiladi.
init funksiyasi #
package main
import "fmt"
var sozlama = tayyorla()
func tayyorla() string {
fmt.Println("1. o'zgaruvchi tayyorlandi")
return "asosiy"
}
func init() {
fmt.Println("2. init ishladi:", sozlama)
}
func main() {
fmt.Println("3. main ishladi")
}
1. o'zgaruvchi tayyorlandi
2. init ishladi: asosiy
3. main ishladi
init - paket yuklanganda avtomatik chaqiriladigan funksiya.
U main dan oldin ishlaydi.
Tartib qat'iy: avval paket o'zgaruvchilari, keyin init, keyin
main.
Bitta faylda bir nechta init bo'lishi mumkin va ularni
chaqirish tartibi doim ravshan emas.
Asosiy muammo - init yashirin ishlaydi. Kodni o'qiyotgan
odam uni ko'rmasligi mumkin, lekin u dastur holatini o'zgartirib
qo'yadi. Testlarda esa uni o'chirib bo'lmaydi.
Ko'p hollarda oddiy funksiya yozib, uni main da ochiq chaqirgan
ma'qul.
Hujjatlash #
// Package hisob oddiy matematik amallarni bajaradi.
package hisob
// Qosh ikki sonning yig'indisini qaytaradi.
//
// Salbiy sonlar ham qabul qilinadi.
func Qosh(a, b int) int {
return a + b
}
Go da hujjat - bu oddiy izoh. Alohida sintaksis yo'q.
Qoida: izoh e'lon qilinayotgan nom bilan boshlanishi kerak -
Qosh ikki sonning....
Keyin uni ko'rish mumkin:
go doc misol.uz/maktab/hisob Qosh
Aynan shu izohlardan pkg.go.dev saytidagi hujjatlar yasaladi.
Foydali standart paketlar #
| Paket | Nima uchun |
|---|---|
fmt | Chiqarish va formatlash |
strings | Satrlar |
strconv | Turlar orasida o'tkazish |
errors | Xatolar |
slices / maps | Kolleksiyalar |
os | Fayllar va muhit |
time | Vaqt |
encoding/json | JSON |
net/http | Veb server va mijoz |
sync | Parallellik |
testing | Testlar |
package main
import (
"fmt"
"os"
"strings"
"time"
)
func main() {
muddat := 90 * time.Minute
fmt.Println(muddat)
fmt.Println(muddat.Hours())
yol := strings.Join([]string{"hujjatlar", "hisobot.txt"}, "/")
fmt.Println(yol)
fmt.Println(len(os.Args) > 0)
}
1h30m0s
1.5
hujjatlar/hisobot.txt
true
time.Duration ning String() metodi bor - shuning uchun
90 * time.Minute odam o'qiy oladigan shaklda chiqdi.
Bu misolda time.Now() ishlatilmadi, chunki u har safar boshqa
natija berardi.
Xuddi shu sabab bilan bu darslikda tasodifiy sonlar, gorutina navbati va map tartibi ham hech qachon to'g'ridan-to'g'ri chiqarilmaydi.
go mod initbilan modul yarating.hisobpapkasini ochib, unga paket yozing.- Katta va kichik harfli funksiya yozib, farqini sinang.
- Paketni
maindan import qilib ishlating. - Import taxallusi bilan ikki paketni chaqiring.
go mod tidyni ishga tushiring vago.modo'zgarishini ko'ring.go.sumfaylini ochib, ichidagini ko'ring.internalpapkasi yaratib, tashqaridan import qilishga urining.initfunksiyasi yozib, chaqirilish tartibini kuzating.- Funksiyaga izoh yozib,
go docbilan ko'ring.
Xulosa #
- Paket - bitta papka; modul -
go.modbor papka va uning ichidagilar. - Ko'rinuvchanlikni nomning birinchi harfi hal qiladi: katta - tashqariga chiqadi.
- Import yo'li - papka yo'li, kodda esa paket nomi ishlatiladi.
_importi faqatinituchun; nuqtali importdan saqlaning.go mod tidybog'liqliklarni kod bo'yicha tartibga soladi.go.sumbog'liqliklarning barmoq izini saqlaydi - uni ham git ga qo'shing.internalpapkasi faqat shu modul ichidan ko'rinadi.initmaindan oldin ishlaydi, lekin uni kam ishlating.- Hujjat - oddiy izoh; u e'lon qilinayotgan nom bilan boshlanadi.
Keyingi bo'limda generiklarni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.