โ† Semua pembelajaran / Go Nol โ†’ Enterprise
Fase 1 ยท Tipe, Interface & Error

Penamaan, komentar & API yang enak dipakai

Go punya sedikit sekali aturan gaya, tapi yang sedikit itu dipatuhi hampir universal. Mengikutinya membuat kodemu terbaca oleh orang yang belum pernah melihat repomu.

Sumber asli go.dev Resmi Rangkuman ~6 menit baca

Intisari

  • Nama pendek untuk umur pendek: i, r, buf. Nama panjang untuk yang diekspor dan berumur panjang.
  • Nama diperpendek oleh konteks: di paket produk, tulis produk.Cari, bukan produk.CariProduk.
  • Singkatan tetap satu kesatuan huruf: userID, HTTPServer, URLPath โ€” bukan userId.
  • Komentar dokumentasi diawali nama yang dijelaskannya dan berupa kalimat lengkap.
  • Interface satu method biasanya dinamai kata kerja + -er: Reader, Formatter, Penyimpan.

Panjang nama sebanding dengan jaraknya

// Pendek โ€” hidupnya tiga baris, konteksnya jelas
for i, p := range daftar {
	if p.Harga > batas {
		hasil = append(hasil, p)
	}
}

// Panjang โ€” diekspor, dibaca orang yang tidak melihat isinya
func HitungOngkirBerdasarkanZona(ctx context.Context, tujuan Alamat) (Rupiah, error)

Ini kebalikan dari kebiasaan di beberapa bahasa lain, di mana nama panjang dianggap selalu lebih baik. Di Go, i di dalam loop tiga baris lebih jelas daripada indeksProdukSaatIni, karena pembaca bisa melihat seluruh hidupnya dalam satu pandangan.

KonteksNama yang lazim
Penerima methodSatu-dua huruf dari nama tipe: func (p *Pesanan)
Handler HTTPw http.ResponseWriter, r *http.Request โ€” selalu
Contextctx, selalu parameter pertama
Errorerr
Loopi, k, v

Konteks paket sudah jadi awalan

โŒโœ…
produk.CariProduk()produk.Cari()
auth.AuthMiddlewareauth.Middleware
config.ConfigLoad()config.Muat()
http.HTTPClienthttp.Client

Yang dibaca di tempat pemakaian adalah paket.Nama secara utuh, jadi rancanglah kalimat itu. bytes.Buffer, time.Now, slices.Sort โ€” semuanya terbaca sebagai frasa.

Singkatan tidak pernah dipecah

userID     ID      URL      HTTPServer     apiKey    XMLData
// bukan:
userId     Id      Url      HttpServer     ApiKey    XmlData

Aturannya: singkatan ditulis konsisten seluruhnya besar atau seluruhnya kecil, tergantung apakah nama itu diekspor. xmlData (privat) dan XMLData (publik), tidak pernah XmlData. Linter revive dan staticcheck menegakkannya (Fase 8).

Komentar dokumentasi

// Package produk berisi model dan aturan bisnis katalog produk.
//
// Paket ini tidak tahu apa pun tentang HTTP maupun database; penyimpanan
// diakses lewat interface yang dideklarasikan di sini.
package produk

// ErrTidakDitemukan dikembalikan saat produk yang diminta tidak ada.
// Lapisan HTTP memetakannya jadi 404.
var ErrTidakDitemukan = errors.New("produk tidak ditemukan")

// Cari mengembalikan produk yang namanya mengandung kata, diurutkan dari
// yang paling murah. Ia mengembalikan slice kosong (bukan error) kalau tidak
// ada yang cocok.
//
// Kata dibandingkan tanpa memperhatikan huruf besar-kecil.
func Cari(ctx context.Context, kata string) ([]Produk, error) {
AturanAlasan
Diawali nama yang dijelaskango doc dan pkg.go.dev memotong per kalimat pertama
Kalimat lengkap, diakhiri titikIa muncul sebagai deskripsi di daftar, di luar konteks kodenya
Jelaskan apa dan kenapa, bukan bagaimana"Bagaimana" ada di kodenya, dan berubah lebih cepat
Sebutkan perilaku tepiNil? Slice kosong? Aman dipanggil dari banyak goroutine? Itu yang dicari pembaca
go doc ./internal/produk          # baca dokumentasi paketmu sendiri
go doc ./internal/produk Cari     # satu simbol
go doc -http=:6060                # jelajahi seluruh modul di browser

Komentar yang tidak menambah apa-apa lebih buruk daripada tidak ada komentar, karena ia ikut membusuk. // Cari mencari hanya menambah baris yang harus dijaga tetap benar. Yang layak ditulis adalah keputusan: kenapa batasnya 100, kenapa urutannya begitu, kenapa fungsi ini tidak mengembalikan error.

Nama interface dan konstruktor

// Satu method: kata kerja + -er
type Reader interface   { Read(...) }
type Penyimpan interface { Simpan(...) }

// Beberapa method: nama peran, bukan -er yang dipaksakan
type PenyimpanProduk interface {
	Ambil(ctx context.Context, id int64) (Produk, error)
	Simpan(ctx context.Context, p Produk) error
}

// Konstruktor
func New(...) *Layanan          // kalau paketnya cuma punya satu tipe utama
func NewLayanan(...) *Layanan   // kalau ada beberapa

Yang membuat API enak dipakai

  1. ctx context.Context selalu parameter pertama, dan tidak pernah disimpan di dalam struct.
  2. error selalu nilai kembalian terakhir.
  3. Nilai nol yang berguna โ€” kalau tipemu perlu konstruktor, itu keputusan sadar.
  4. Terima interface, kembalikan struct.
  5. Jangan kembalikan nilai kembalian tak bernama yang lebih dari dua โ€” tiga nilai anonim adalah tanda struct hasil dibutuhkan.
  6. Fungsi yang bisa gagal harus mengembalikan error, bukan mencatat log lalu diam.

Latihan: ambil satu paket yang sudah kamu tulis, jalankan go doc padanya, dan baca hasilnya seolah kamu belum pernah melihat kode itu. Perbaiki setiap nama yang terbaca berulang (produk.ProdukX), lalu tulis komentar paket satu paragraf yang menjelaskan apa yang paket ini tidak tahu.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.