Pendahuluan
Belajar bahasa pemrograman bukan sekadar belajar menulis baris-baris kode. Yang lebih penting adalah belajar mengubah masalah menjadi langkah-langkah yang dapat dijalankan oleh komputer. Go membantu proses itu karena bahasanya relatif kecil, aturan penulisannya konsisten, dan perkakas resminya terintegrasi sejak awal. Go dirancang di Google untuk menjawab persoalan rekayasa perangkat lunak berskala besar: kode harus mudah dibaca, cepat dikompilasi, mudah diuji, dan mampu menangani pekerjaan konkuren dengan model yang lebih sederhana daripada banyak pendekatan tradisional berbasis thread manual (Pike, 2012).
Buku ini ditulis untuk membawa Anda dari titik nol menuju kemampuan membangun program nyata: program command-line, layanan web, program yang membaca dan menulis data, program yang diuji, serta aplikasi konkuren yang dapat menangani banyak pekerjaan sekaligus. Kita akan bergerak bertahap. Pada awalnya, Anda hanya perlu memahami apa itu program dan bagaimana menjalankannya. Setelah itu, kita akan membangun pemahaman tentang nilai, variabel, fungsi, struktur data, error, package, testing, konkurensi, web, database, keamanan dasar, sampai deployment.
Tujuan buku ini bukan membuat Anda menghafal seluruh fitur Go. Tujuannya adalah membuat Anda dapat berpikir dan bekerja sebagai programmer Go yang rapi: menulis kode yang jelas, memahami pesan galat, memecah masalah menjadi bagian kecil, menguji perilaku program, dan mengambil keputusan teknis yang masuk akal.
Mengapa Go layak dipelajari?
Go adalah bahasa pemrograman yang dikompilasi. Artinya, kode sumber yang Anda tulis akan diterjemahkan oleh compiler menjadi program yang dapat dijalankan oleh komputer. Kode sumber adalah teks yang ditulis manusia, misalnya file main.go. Compiler adalah program yang memeriksa kode tersebut, memastikan aturan bahasanya benar, lalu menghasilkan binary atau menjalankan program melalui perkakas Go.
Contoh paling sederhana terlihat seperti ini:
package main
import "fmt"
func main() {
fmt.Println("Halo, Go!")
}
Walaupun pendek, program ini sudah memperlihatkan beberapa ide dasar. package main menyatakan bahwa file ini bagian dari program yang dapat dijalankan. import "fmt" mengambil package standar bernama fmt untuk melakukan pemformatan teks. func main() adalah fungsi utama tempat eksekusi program dimulai. Baris fmt.Println("Halo, Go!") mencetak teks ke layar.
Go terkenal bukan karena memiliki sintaks sebanyak mungkin, melainkan karena menjaga bahasa tetap sederhana. Spesifikasi bahasa Go relatif ringkas dibandingkan banyak bahasa industri lain, dan banyak perilaku pentingnya dijelaskan secara eksplisit dalam dokumentasi resmi (The Go Authors, n.d.-a). Kesederhanaan ini penting dalam proyek besar. Jika banyak orang membaca dan mengubah kode yang sama, kode yang mudah dipahami sering kali lebih bernilai daripada kode yang sangat “cerdas” tetapi sulit dirawat.
Go juga memiliki standard library yang kuat. Standard library adalah kumpulan package bawaan yang tersedia tanpa perlu memasang dependensi eksternal. Misalnya, Go menyediakan package untuk memproses teks, bekerja dengan file, melakukan testing, menulis server HTTP, encoding JSON, dan banyak tugas umum lain. Package net/http, misalnya, menyediakan komponen untuk membuat HTTP client dan server langsung dari standard library (The Go Authors, n.d.-b). Ini membuat Go sangat cocok untuk layanan web dan sistem backend.
Selain itu, Go memiliki dukungan konkurensi sebagai bagian utama dari bahasa. Konkurensi adalah kemampuan program mengelola banyak pekerjaan yang sedang berlangsung dalam rentang waktu yang sama. Konkurensi tidak selalu berarti semua pekerjaan benar-benar berjalan pada detik yang sama di banyak inti CPU; itu adalah paralelisme. Konkurensi lebih umum: program dapat menyusun pekerjaan sehingga beberapa tugas tampak berjalan bersama, misalnya menerima request web, membaca database, dan menunggu respons jaringan.
Go menyediakan goroutine dan channel untuk membantu menulis program konkuren. Goroutine adalah fungsi yang dijalankan secara konkuren oleh runtime Go. Channel adalah jalur komunikasi bertipe antara goroutine. Salah satu prinsip desain yang sering dikutip dalam komunitas Go adalah “jangan berkomunikasi dengan berbagi memori; bagikan memori dengan berkomunikasi” (Cox, 2010). Maksudnya, alih-alih beberapa bagian program mengubah data yang sama secara sembarangan, kita dapat merancang aliran komunikasi yang lebih jelas.
Contoh kecilnya:
package main
import "fmt"
func main() {
pesan := make(chan string)
go func() {
pesan <- "selesai"
}()
fmt.Println(<-pesan)
}
Program ini membuat channel pesan, menjalankan goroutine, lalu menerima nilai dari channel tersebut. Kita belum perlu memahami semua detailnya sekarang. Yang penting, Anda mulai melihat bahwa Go menyediakan bentuk bawaan untuk mengekspresikan kerja konkuren secara ringkas.
Apa yang dimaksud “dari nol hingga mahir”?
“Dari nol” berarti buku ini tidak menganggap Anda sudah menguasai Go. Namun, karena level buku ini adalah sarjana, penjelasan akan tetap menggunakan ketelitian konseptual. Kita akan mulai dari definisi dasar, tetapi tidak menghindari istilah teknis yang memang perlu. Istilah baru akan diperkenalkan sebelum dipakai secara intensif.
“Mahir” dalam buku ini tidak berarti mengetahui setiap sudut bahasa Go. Mahir berarti Anda dapat membangun program yang benar, dapat diuji, dapat dibaca, dan dapat dikembangkan. Seorang programmer Go yang mahir tidak hanya bertanya, “Bagaimana agar kode ini jalan?” Ia juga bertanya:
- Apakah struktur data yang dipakai sesuai?
- Apakah error ditangani secara eksplisit?
- Apakah fungsi ini terlalu besar?
- Apakah package ini punya tanggung jawab yang jelas?
- Apakah program ini aman dari data race?
- Apakah API ini mudah dipakai oleh programmer lain?
- Apakah layanan ini bisa dikonfigurasi, diuji, dan dijalankan di lingkungan produksi?
Pertanyaan-pertanyaan itu akan muncul secara bertahap sepanjang buku. Pada bab awal, kita fokus pada bahasa. Pada bab tengah, kita mulai menyusun program yang lebih besar. Pada bab akhir, kita belajar membangun aplikasi yang lebih dekat dengan kebutuhan dunia nyata: web service, database, keamanan dasar, observabilitas, dan deployment.
Cara berpikir yang akan kita latih
Pemrograman dimulai dari masalah. Masalah adalah keadaan yang ingin kita ubah dengan langkah-langkah terstruktur. Misalnya, “hitung total harga belanja”, “validasi alamat email”, “simpan data pengguna”, atau “layani request HTTP untuk membuat artikel baru”.
Dari masalah, kita menyusun algoritma. Algoritma adalah urutan langkah yang jelas untuk menyelesaikan masalah. Sebelum menulis kode, kita bisa menulis algoritma dalam bahasa sehari-hari.
Misalnya, masalahnya: menghitung total belanja setelah diskon.
Algoritmanya:
- Terima harga awal.
- Terima persentase diskon.
- Hitung nilai diskon.
- Kurangi harga awal dengan nilai diskon.
- Tampilkan hasil akhir.
Dalam Go, algoritma itu dapat berubah menjadi kode seperti ini:
package main
import "fmt"
func main() {
harga := 200000.0
diskon := 0.15
nilaiDiskon := harga * diskon
total := harga - nilaiDiskon
fmt.Println(total)
}
Kode ini belum sempurna untuk aplikasi produksi. Misalnya, uang sebaiknya tidak selalu dimodelkan dengan float64 karena representasi bilangan pecahan biner dapat menimbulkan persoalan presisi dalam perhitungan finansial. Namun sebagai contoh awal, kode ini cukup untuk menunjukkan hubungan antara masalah, algoritma, data, dan eksekusi.
Data adalah informasi yang diproses program. Dalam contoh tadi, harga, diskon, nilaiDiskon, dan total adalah data. Setiap data memiliki tipe. Tipe memberi tahu program jenis nilai apa yang sedang dipakai dan operasi apa yang masuk akal untuk nilai tersebut. Angka dapat dijumlahkan; teks dapat digabungkan; nilai boolean dapat dipakai dalam percabangan. Go adalah bahasa dengan static typing, yaitu tipe diperiksa pada waktu kompilasi. Jika Anda mencoba memakai nilai dengan cara yang tidak sesuai tipenya, compiler akan memberi galat sebelum program berjalan. Spesifikasi Go menjelaskan sistem tipe ini sebagai bagian inti dari bahasa (The Go Authors, n.d.-a).
Eksekusi program adalah proses ketika instruksi program dijalankan. Pada program sederhana, eksekusi tampak bergerak dari atas ke bawah. Namun, setelah kita mempelajari fungsi, percabangan, perulangan, goroutine, dan komunikasi jaringan, alur eksekusi bisa menjadi lebih kaya. Salah satu tugas penting programmer adalah membuat alur itu tetap dapat dipahami.
Go sebagai alat rekayasa perangkat lunak
Go bukan hanya bahasa. Go hadir bersama toolchain, yaitu kumpulan perkakas resmi untuk membangun, menjalankan, menguji, memformat, dan mengelola dependensi program. Perintah seperti go run, go build, go test, go fmt, dan go mod tidy akan sering kita pakai.
Ini penting karena pemrograman modern bukan hanya menulis kode. Kita perlu:
- menjalankan program dengan cepat saat bereksperimen;
- membangun binary yang siap didistribusikan;
- menulis test untuk memeriksa perilaku program;
- memformat kode agar konsisten;
- mengelola package eksternal;
- mendeteksi potensi masalah sebelum program dipakai pengguna.
Dokumentasi resmi Go menekankan alur kerja berbasis module untuk mengelola kode dan dependensi, termasuk pembuatan file go.mod pada proyek modern (The Go Authors, n.d.-c). Module adalah unit versi dan dependensi dalam Go. Dengan module, sebuah proyek dapat menyatakan package eksternal apa yang dipakai dan versi mana yang dibutuhkan.
Sebagai contoh, proyek kecil Go biasanya dimulai dari direktori yang memiliki file seperti ini:
contoh-proyek/
├── go.mod
└── main.go
File main.go berisi kode program. File go.mod menjelaskan identitas module dan versi Go yang dipakai. Struktur sederhana ini akan berkembang ketika program makin besar, tetapi prinsipnya tetap sama: kode harus diorganisasi agar mudah dipahami.
Apa yang akan Anda bangun?
Buku ini bergerak dari program kecil menuju aplikasi lengkap. Pada awalnya, Anda akan menulis program yang mencetak teks, menghitung nilai, membaca input, dan memakai fungsi. Setelah itu, Anda akan memodelkan data dengan struct, mengelola koleksi data dengan slice dan map, serta menangani error secara eksplisit.
Error handling adalah salah satu ciri penting Go. Dalam banyak situasi, fungsi Go mengembalikan dua nilai: hasil dan error. Jika error tidak nil, berarti operasi gagal atau tidak selesai seperti yang diharapkan. Pola ini membuat kegagalan terlihat jelas di kode. Buku The Go Programming Language menekankan gaya Go yang eksplisit dan sederhana dalam menyusun program, termasuk penggunaan nilai balik dan error untuk mengendalikan alur program (Donovan & Kernighan, 2015).
Contoh sederhana:
data, err := os.ReadFile("config.json")
if err != nil {
return err
}
fmt.Println(string(data))
Di sini, os.ReadFile mencoba membaca file. Jika gagal, misalnya karena file tidak ada, err berisi informasi kegagalan. Kita tidak berpura-pura bahwa operasi file selalu berhasil. Kita memeriksanya.
Pada bagian web, Anda akan membuat server HTTP. HTTP adalah protokol yang dipakai browser dan banyak aplikasi untuk berkomunikasi melalui request dan response. Request adalah permintaan dari client, misalnya “ambil daftar artikel”. Response adalah jawaban dari server, misalnya data JSON berisi daftar artikel. Dengan package net/http, Go memungkinkan kita membangun server seperti ini:
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/halo", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Halo dari server Go")
})
http.ListenAndServe(":8080", nil)
}
Program ini menjalankan server pada port 8080. Ketika pengguna membuka /halo, server mengirim teks sebagai response. Kelak kita akan membahas status code, header, middleware, routing, JSON API, dan struktur aplikasi web yang lebih rapi.
Pada bagian konkurensi, Anda akan belajar menulis program yang melakukan banyak pekerjaan tanpa membuat kode menjadi kacau. Pada bagian database, Anda akan belajar menyimpan data secara persisten. Persistensi berarti data tetap ada walaupun program berhenti berjalan. Pada bagian keamanan, Anda akan belajar prinsip dasar seperti hashing password, validasi input, dan pengelolaan secret. Pada bagian deployment, Anda akan menyiapkan program agar dapat dijalankan di lingkungan nyata.
Sikap belajar yang disarankan
Go sering terasa sederhana pada awalnya, tetapi kesederhanaan itu bukan alasan untuk belajar terburu-buru. Banyak kesalahan dalam pemrograman muncul bukan karena seseorang tidak tahu fitur yang canggih, melainkan karena ia melewati dasar: tipe data, scope, error, alur eksekusi, dan struktur program.
Saat membaca buku ini, biasakan tiga kebiasaan.
Pertama, jalankan contoh. Kode yang hanya dibaca sering terasa lebih jelas daripada kenyataannya. Dengan menjalankan kode, Anda akan melihat output, pesan galat, dan perilaku aktual program.
Kedua, ubah contoh sedikit. Jika contoh memakai harga := 200000.0, ubah nilainya. Jika fungsi menerima string, coba string kosong. Jika program membaca file, coba nama file yang tidak ada. Eksperimen kecil seperti ini mengubah pengetahuan pasif menjadi pemahaman aktif.
Ketiga, baca pesan galat dengan tenang. Pesan galat bukan musuh. Pesan galat adalah informasi dari compiler, runtime, test, atau tool lain. Programmer yang baik tidak menebak-nebak terlalu lama; ia membaca pesan, mencari lokasi masalah, lalu memperbaiki penyebabnya.
Go mendukung kebiasaan ini dengan perkakas yang konsisten. gofmt, misalnya, memformat kode Go secara otomatis sehingga tim tidak perlu berdebat panjang tentang gaya indentasi dan tata letak. Dokumen Effective Go menjelaskan banyak idiom penulisan Go, termasuk penamaan, struktur program, dan gaya yang lazim dipakai komunitas Go (The Go Authors, n.d.-d). Kita akan memakai idiom tersebut secara bertahap, bukan menghafalnya sekaligus.
Peta perjalanan buku
Bab 1 memperkenalkan Go dan cara berpikir programmer. Bab 2 menyiapkan lingkungan pengembangan. Bab 3 sampai Bab 8 membangun fondasi bahasa: struktur program, nilai, variabel, tipe data, operator, alur kendali, fungsi, array, slice, map, string, rune, byte, dan Unicode.
Bab 9 sampai Bab 13 mulai membahas desain program yang lebih serius: struct, method, interface, pointer, error handling, package, module, dan dependensi. Di sini Anda akan belajar bahwa program yang baik bukan hanya “berjalan”, tetapi juga punya bentuk yang dapat dirawat.
Bab 14 dan Bab 15 membahas input-output, file, JSON, testing, benchmarking, dan kualitas kode. Ini adalah jembatan menuju pekerjaan pemrograman nyata, karena hampir semua aplikasi harus membaca data, menulis data, dan diuji.
Bab 16 dan Bab 17 membahas konkurensi, goroutine, channel, sinkronisasi, dan context. Ini bagian penting dalam Go, tetapi kita akan memasukinya setelah fondasi bahasa cukup kuat.
Bab 18 sampai Bab 21 membawa Anda ke aplikasi web, database, arsitektur aplikasi, dan keamanan dasar. Bab 22 membahas generics, yaitu kemampuan menulis fungsi dan tipe yang bekerja untuk beberapa tipe sekaligus melalui type parameter. Bab 23 membahas aplikasi command-line dan otomasi. Bab 24 menutup perjalanan teknis dengan deployment, observabilitas, profiling, dan proyek akhir.
Pada akhir buku, Anda diharapkan mampu membangun layanan web Go yang diuji, menangani error dengan jelas, memakai database secara aman, menjalankan tugas konkuren tanpa data race, dan menyiapkan aplikasi untuk dijalankan di lingkungan yang lebih nyata.
Sebelum mulai
Anda tidak perlu memahami semua istilah dalam pendahuluan ini sekarang. Beberapa istilah sengaja dikenalkan lebih awal agar Anda punya peta. Nanti, setiap konsep akan dibuka perlahan pada bab yang tepat.
Yang perlu Anda bawa ke Bab 1 hanyalah tiga hal: rasa ingin tahu, kesediaan menjalankan contoh, dan keberanian membaca pesan galat. Pemrograman adalah keterampilan praktis. Semakin sering Anda menulis, menjalankan, mengubah, dan memperbaiki program, semakin kuat intuisi Anda.
Kita mulai dari dasar, tetapi tujuan akhirnya jelas: membangun perangkat lunak Go yang benar, sederhana, teruji, dan siap dikembangkan.
References
Cox, R. (2010). Share Memory By Communicating. The Go Blog. https://go.dev/blog/codelab-share
Donovan, A. A. A., & Kernighan, B. W. (2015). The Go Programming Language. Addison-Wesley Professional.
Pike, R. (2012). Go at Google: Language Design in the Service of Software Engineering. Google. https://go.dev/talks/2012/splash.article
The Go Authors. (n.d.-a). The Go Programming Language Specification. https://go.dev/ref/spec
The Go Authors. (n.d.-b). Package net/http. https://pkg.go.dev/net/http
The Go Authors. (n.d.-c). Tutorial: Get started with Go. https://go.dev/doc/tutorial/getting-started
The Go Authors. (n.d.-d). Effective Go. https://go.dev/doc/effective_go