Program Go yang paling sederhana sekalipun selalu tersusun dari bagian-bagian yang sama, dan Go sengaja menjaga jumlah bagian tersebut tetap kecil. Dengan mengenali anatomi program sejak awal, kita dapat membaca kode Go milik siapa pun tanpa menebak-nebak aturan yang berlaku. Pada chapter ini kita membedah satu program utuh ke dalam empat bagian penyusunnya: package, import, fungsi, dan statement. Pemahaman ini menjadi pondasi bagi seluruh contoh pada chapter berikutnya di section Program Pertama.

Empat Bagian Penyusun Program #

Setiap berkas .go pada dasarnya berdiri di atas empat jenis bagian berikut:

BagianBentuk umumPeran
Package clausepackage mainMemberi identitas berkas dan menandai jenis program
Import declarationimport "fmt"Memuat package lain yang dibutuhkan kode
Deklarasi fungsifunc main() { ... }Membungkus blok kode dengan sebuah nama
Statementfmt.Println(pesan)Instruksi tunggal yang dieksekusi oleh runtime

Statement dieksekusi berurutan dari atas ke bawah di dalam fungsi yang menampungnya. Fungsi memungkinkan kita mengelompokkan beberapa statement menjadi satu unit yang dapat dipanggil berulang kali. Import declaration menghubungkan berkas kita dengan package lain, misalnya package fmt untuk mencetak teks. Terakhir, package clause menentukan berkas ini termasuk ke dalam package mana sehingga compiler tahu cara mengompilasinya.

Satu unsur lagi kerap muncul berdampingan dengan keempat bagian di atas, yaitu komentar. Komentar ditulis dengan awalan // atau diapit pasangan /* dan */, lalu diabaikan sepenuhnya oleh compiler. Peran komentar murni untuk pembaca manusia: menjelaskan maksud kode tanpa mengubah perilaku program sedikit pun.

Program Contoh Utuh #

Berkas struktur.go pada folder chapter ini memuat program yang menggunakan keempat bagian tersebut. Sebelum membaca bedahnya, jalankan program ini dengan go run struktur.go dari folder chapter, lalu cocokkan hasilnya dengan blok output di bawah:

go
package main

import "fmt"

// sapa mengembalikan salam untuk nama yang diberikan.
func sapa(nama string) string {
	return "Halo, " + nama
}

func main() {
	pesan := sapa("Budi")
	fmt.Println(pesan)
	fmt.Println("Struktur program sudah lengkap.")
}

Output yang Dihasilkan:

text
Halo, Budi
Struktur program sudah lengkap.

Mari kita telaah baris demi baris program di atas:

  1. Baris 1 (package main): package clause yang menyatakan berkas ini bagian dari package main, penanda program yang dapat dieksekusi.
  2. Baris 3 (import "fmt"): import declaration yang memuat package fmt dari standard library agar fungsinya dapat dipanggil.
  3. Baris 5 (// sapa ...): komentar dokumentasi singkat yang menjelaskan fungsi di bawahnya; komentar diawali tanda //.
  4. Baris 6 (func sapa(nama string) string {): deklarasi fungsi sapa dengan satu parameter nama bertipe string dan nilai balik bertipe string.
  5. Baris 7 (return "Halo, " + nama): statement return yang mengembalikan hasil penggabungan dua string memakai operator +.
  6. Baris 10 (func main() {): deklarasi fungsi main, titik masuk yang dicari runtime saat program dijalankan.
  7. Baris 11 (pesan := sapa("Budi")): statement yang memanggil fungsi sapa lalu menampung nilai baliknya ke dalam variabel pesan.
  8. Baris 12-13 (fmt.Println(pesan) dan fmt.Println("...")): dua statement yang mencetak nilai variabel dan string ke layar secara berurutan.

Eksekusi dari Atas ke Bawah #

Runtime menjalankan statement di dalam fungsi satu per satu, mulai baris pertama sampai baris terakhir. Pada struktur.go, pemanggilan sapa("Budi") harus tuntas lebih dulu sebelum fmt.Println(pesan) dapat mencetak apa pun, karena nilai pesan baru terisi setelah pemanggilan tersebut selesai. Urutan seperti ini membuat alur program Go dapat dibaca secara linear tanpa perlu melacak lompatan.

Berbeda dari banyak bahasa keluarga C, kode Go jarang menutup statement dengan titik koma. Compiler menyisipkan titik koma secara otomatis di akhir baris sesuai aturan pada spesifikasi resmi. Konsekuensinya, cara memenggal statement menjadi penting: kata return yang ditulis terpisah dari nilai baliknya akan dianggap statement return tanpa nilai. Karena aturan yang sama, kurung kurawal pembuka { wajib menempel di ujung baris deklarasi fungsi, bukan turun sendiri ke baris baru.

Urutan Bagian yang Terikat Aturan #

Penempatan keempat bagian tersebut tidak sepenuhnya bebas. Package clause wajib menjadi pernyataan pertama yang tidak berupa komentar pada setiap berkas .go. Import declaration hanya boleh muncul setelah package clause dan sebelum deklarasi fungsi maupun statement. Sementara itu, urutan antar fungsi bebas: fungsi main boleh dideklarasikan paling awal, paling akhir, atau di tengah berkas, dan compiler tidak memedulikan posisinya.

Aturan urutan ini membuat struktur program Go mudah diprediksi. Saat kita membuka berkas Go yang belum pernah dilihat, package clause selalu ada di puncak berkas, import selalu berkelompok setelahnya, lalu fungsi dan isinya menyusul. Perataan indentasi memakai tab, seperti pada contoh di atas, adalah gaya resmi Go yang dijaga oleh perintah gofmt dan dibahas di chapter gofmt .

Dengan anatomi yang sudah dikenali, kita siap memperdalam bagian pertama dari struktur tersebut: package clause, dan khususnya alasan kenapa program yang dapat dieksekusi wajib bernama main. Pembahasan lengkapnya menanti di chapter berikutnya.

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

struktur.go

Unduh berkas
go
package main

import "fmt"

// sapa mengembalikan salam untuk nama yang diberikan.
func sapa(nama string) string {
	return "Halo, " + nama
}

func main() {
	pesan := sapa("Budi")
	fmt.Println(pesan)
	fmt.Println("Struktur program sudah lengkap.")
}