Modül, kökünde bir go.mod dosyası olan bir Go paketleri dizin ağacıdır. go.mod modülü adlandırır ve bağımlı olduğu diğer her modülün sürümlerini listeler. Bir tane go mod init ile oluşturursunuz:
mkdir myapp
cd myapp
go mod init example.com/myapp
go: creating new go.mod: module example.com/myapp
Ortaya çıkan go.mod:
module example.com/myapp
go 1.24.5
Derlemek için bu yeterlidir. Go 1.16'dan beri her Go projesi bir modüldür ve go build, go run . ve go test modül olmadan çalışmayı reddeder:
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
Modül Yolunu Seçmek
Modül yolu, modülün içindeki her import yolunun önekidir. example.com/myapp modülünde internal/store dizinindeki bir paket example.com/myapp/internal/store olarak import edilir.
| Durum | Modül yolu |
|---|---|
| GitHub'da barındırılan ve başkalarının import edebileceği kod | github.com/yourname/project |
| Şirketinizin kodu | yourcompany.com/project ya da depo URL'si |
| Özel bir program ya da alıştırma | example.com/myapp ya da yalnızca myapp |
| Yayımlanmış bir modülün 2. ya da sonraki sürümü | github.com/yourname/project/v2 |
Bir kütüphane için yol kodun bulunduğu yerle eşleşmelidir, çünkü go get depoyu bulmak için onu kullanır. Yalnızca sizin çalıştırdığınız bir program için yol sadece bir addır. go mod init fmt ya da go mod init strings gibi bir standart kütüphane paketiyle eşleşen tek bir kelimeden kaçının: derleme o zaman ambiguous import: found package fmt in multiple modules ile başarısız olur.
Eski GOPATH düzeninin dışında argümansız go mod init çalıştırmak başarısız olur:
go: cannot determine module path for source directory /home/ana/myapp (outside GOPATH, module path must be specified)
Ona bir yol verin.
Bağımlılık Eklemek
Import'u yazın, sonra Go'nun onu getirmesine izin verin. main.go'nun github.com/google/uuid'yi import ettiğini varsayalım. Modül onu bilmeden derlemek açık bir talimat verir:
main.go:6:2: no required module provides package github.com/google/uuid; to add it:
go get github.com/google/uuid
İki komuttan biri bunu düzeltir:
go get github.com/google/uuid
# or, to sync go.mod with every import in the module:
go mod tidy
go get neyi değiştirdiğini bildirir:
go: downloading github.com/google/uuid v1.6.0
go: added github.com/google/uuid v1.6.0
go mod tidy import'u nasıl çözdüğünü bildirir:
go: finding module for package github.com/google/uuid
go: downloading github.com/google/uuid v1.6.0
go: found github.com/google/uuid in github.com/google/uuid v1.6.0
go.mod'da artık bir require satırı var:
module example.com/myapp
go 1.24.5
require github.com/google/uuid v1.6.0
Sürümlerle go get
| Komut | Etkisi |
|---|---|
go get pkg | pkg'yi en son sürümüyle ekler ya da zaten gerekiyorsa mevcut sürümü korur |
go get pkg@v1.5.0 | tam olarak v1.5.0'ı kullanır (yükseltme ya da düşürme) |
go get pkg@latest | en son sürüme geçer |
go get pkg@abc1234 | belirli bir commit'i kullanır (pseudo-version olarak kaydedilir) |
go get -u ./... | her bağımlılığı en son minor ya da patch sürümüne yükseltir |
go get -u=patch ./... | yalnızca en son patch sürümlerine yükseltir |
go get pkg@none | gereksinimi kaldırır |
go get go@1.24 | modülün minimum Go sürümünü yükseltir |
go get, go.mod'u değiştirir. Artık programları derlemez ya da kurmaz; Go 1.18'den beri bu go install pkg@version'ın işidir.
Dolaylı bağımlılıklar
// indirect ile işaretlenen gereksinimler, kodunuzun doğrudan import etmediği ama derlemenin ihtiyaç duyduğu modüllerdir. Go 1.17'den beri go.mod, derlemeye bir paket sağlayan her modülü listeler, bu yüzden bağımlılıklarınızın bağımlılıkları burada bu işaretle görünür. Bu işaretleri go mod tidy yönetir; onları kendiniz eklemezsiniz.
go mod tidy
Import eklediğinizde ya da kaldırdığınızda go mod tidy çalıştırın. Şunları yapar:
- eksik olan import edilmiş paketler için gereksinimler ekler,
- artık hiçbir şeyin import etmediği gereksinimleri kaldırır,
- derlemenin ihtiyaç duyduğu
go.sumgirdilerini ekler ve eskimiş olanları atar.
Testler ve her build tag kombinasyonu dahil modüldeki her pakete bakar, bu yüzden bazen kendi platformunuzda kullanıldığını görmediğiniz bir bağımlılığı tutar. Her commit'ten önce go mod tidy çalıştırmak ve CI'da hiçbir fark üretmediğini kontrol etmek go.mod'u dürüst tutar.
go.sum
go.sum, derlemenin kullandığı her modül sürümü için bir hash kaydeder:
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
İlk satır modülün dosyalarını, ikincisi yalnızca go.mod'unu hash'ler. go komutu bir modülü indirdiğinde hash'i go.sum'a ve genel checksum veritabanına (sum.golang.org) karşı kontrol eder, bu yüzden kurcalanmış ya da sessizce değiştirilmiş bir sürüm derlemeyi başarısız kılar. go.sum'ı go.mod'un yanında commit edin ve onu asla elle düzenlemeyin.
Go Sürümleri Nasıl Seçer
Go minimal version selection kullanır. Her modül her bağımlılığın ihtiyaç duyduğu minimum sürümünü listeler ve derleme bu minimumların en yükseğini kullanır, asla daha yenisini değil. Modülünüz uuid v1.5.0 gerektiriyorsa ve bir bağımlılık uuid v1.6.0 gerektiriyorsa derleme, v1.7.0 var olsa bile v1.6.0'ı kullanır. Biri go get ile istemedikçe hiçbir şey yükseltilmez.
Bunun sonucu, derlemelerin bir lock dosyası olmadan yeniden üretilebilir olmasıdır: go.mod artı bağımlılık grafiği her sürümü tamamen belirler. go list -m all sonucu yazdırır:
go list -m all
example.com/myapp
github.com/google/uuid v1.6.0
Ana sürümler
v2 ya da üzerindeki bir modül ana sürümü yoluna dahil etmelidir: github.com/yourname/project/v2. Import yolu da onunla değişir, bu yüzden project ve project/v2 farklı modüllerdir ve ikisi de tek bir derlemede bulunabilir. Bu, Go'nun geriye uyumsuz değişiklikler için kuralıdır ve github.com/jackc/pgx/v5 gibi import'lar görmenizin nedeni budur.
replace: Bir Bağımlılık Üzerinde Yerel Çalışmak
Bir bağımlılıktaki değişiklikleri yayımlamadan önce test etmek için onun yolunu yerel bir dizine yönlendirin:
module example.com/myapp
go 1.24.5
require example.com/mylib v1.2.0
replace example.com/mylib => ../mylib
Ya da komut satırından:
go mod edit -replace example.com/mylib=../mylib
go mod tidy
Dizin kendi go.mod'unu içermelidir. replace yalnızca bu modülü doğrudan derlerken uygulanır, başka biri ona bağımlı olduğunda değil; bu yüzden bir sürüm etiketlemeden önce onu kaldırmayı unutmayın.
Birkaç modülü go.mod dosyalarına dokunmadan aynı anda düzenlemek için Go 1.18 workspace'leri ekledi:
go work init . ../mylib
Bu, yerel mylib'in öncelik almasını sağlayan bir go.work dosyası yazar. Tüm ekip aynı düzeni kullanmıyorsa go.work'ü sürüm kontrolünün dışında tutun.
Araç Bağımlılıkları (Go 1.24)
Go 1.24, kod üreteçleri ve linter'lar global olarak kurulmak yerine go.mod içinde sürümlenebilsin diye bir tool yönergesi ekledi:
go get -tool golang.org/x/tools/cmd/stringer
go tool stringer -type=Color
func init Başka Bir Şeydir
"golang init" aramaları çoğu zaman go mod init ile ilgisi olmayan init fonksiyonunu kasteder. Her paket func init() tanımlayabilir. Argüman almaz, kodunuz tarafından çağrılamaz ve paket seviyesindeki değişkenler ayarlandıktan sonra ve main'den önce otomatik olarak bir kez çalışır:
Bir dosyanın birkaç init fonksiyonu olabilir ve göründükleri sırayla çalışırlar. Import edilen paketler önce kendi başlatmalarını bitirir. init'i küçük tutun: başarısız olabilecek işleri main'den çağrılan sıradan bir fonksiyon olarak ele almak ve test etmek daha kolaydır.
Özel Modüller ve Proxy'ler
Varsayılan olarak go, modülleri proxy.golang.org üzerinden indirir. Bu proxy özel depoları göremez, bu yüzden Go'ya hangi yolların özel olduğunu söyleyin:
go env -w GOPRIVATE=github.com/yourcompany/*
GOPRIVATE ile eşleşen modüller git kimlik bilgilerinizle doğrudan depodan çekilir ve checksum veritabanını atlar.
Sıkça Sorulan Sorular
go mod init ne yapar?
Mevcut dizinde bir go.mod dosyası oluşturur ve bu da o dizini bir modülün kökü yapar. go mod init example.com/myapp modül yolunu ve Go sürümünü yazar:
module example.com/myapp
go 1.24.5
Onu proje başına bir kez, go build ya da go get'ten önce çalıştırın.
go mod init'te modül yolu olarak ne kullanmalıyım?
Başkaları kodu import ederse kodun çekileceği adresi, genellikle depo yolunu: go mod init github.com/yourname/project. Kimsenin import etmeyeceği bir program için herhangi bir ad işe yarar (go mod init myapp), ama example.com/myapp gibi noktalı, alan adı tarzı bir yol standart kütüphane paket adlarıyla çakışmayı önler.
go get ile go mod tidy arasındaki fark nedir?
go get pkg@version bir bağımlılık ekler ya da sürümünü değiştirir. go mod tidy kaynak dosyalarınızı okur, import'larınızın ihtiyaç duyduğu ama go.mod'da olmayan her modülü ekler, hiçbir şeyin import etmediği gereksinimleri kaldırır ve go.sum'ı günceller. Yaygın bir akış, import'u yazıp ardından go mod tidy çalıştırmaktır.
go.sum'ı commit etmeli miyim?
Evet. go.sum, derlemenizin kullandığı her modül sürümünün kriptografik hash'lerini tutar. Onu commit etmek, go komutunun herkesin bayt bayt aynı bağımlılıkları indirdiğini doğrulamasını sağlar. Onu asla elle düzenlemeyin; go mod tidy onu yönetir.
"golang init" ile go mod init aynı şey mi?
Hayır, bir kelimeyi paylaşan farklı şeylerdir. go mod init, go.mod oluşturan bir terminal komutudur. func init() ise Go kodunda yazdığınız bir fonksiyondur; paketin değişkenleri başlatıldıktan sonra, main'den önce otomatik olarak bir kez çalışır.