Menu

For Loop di Golang: Keempat Bentuknya dengan Contoh

Go hanya punya satu kata kunci perulangan, for, dan itu mencakup semuanya: loop counter tiga klausa, loop while yang hanya berisi kondisi, loop tak terbatas, dan range atas slice, map, string, channel, integer, serta fungsi. Ditambah break dan continue berlabel serta perubahan variabel loop di Go 1.22.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Go hanya punya satu kata kunci perulangan: for. Kata kunci ini punya empat bentuk, dan keempatnya mencakup setiap perulangan yang biasa kamu tulis dengan for, while, do while, atau foreach di bahasa lain.

Header loop tidak diapit tanda kurung, dan kurung kurawal selalu wajib.

Loop Tiga Klausa

for init; condition; post {
	// body
}
  1. init berjalan sekali sebelum loop. Biasanya berupa deklarasi variabel singkat seperti i := 0, dan variabel itu hanya ada di dalam loop.
  2. condition diperiksa sebelum setiap iterasi. Saat bernilai false, loop berakhir.
  3. Badan loop dijalankan.
  4. post berjalan setelah setiap iterasi, biasanya i++.

Di Go, i++ adalah pernyataan, bukan ekspresi, jadi post tidak bisa berisi i++, j--. Pakai assignment paralel sebagai gantinya: i, j = i+1, j-1.

Ketiga klausa itu opsional. for ; i < 10; {} sah, dan gofmt menulisnya ulang menjadi for i < 10 {}, yaitu bentuk berikutnya.

Loop yang Hanya Berisi Kondisi (while ala Go)

Dengan kondisi saja, for berperilaku seperti while di bahasa lain:

Tidak ada do while yang terpisah. Halaman while loop menunjukkan cara mendapatkan perilaku "jalankan minimal sekali".

Loop Tak Terbatas

for tanpa apa pun setelahnya akan berputar selamanya. Tinggalkan dengan break, return, os.Exit, atau panic:

for {
	line, err := reader.ReadString('\n')
	if err != nil {
		break
	}
	process(line)
}

Ini adalah bentuk standar untuk server, worker, dan loop input. for {} dengan badan kosong menghabiskan satu core CPU; di kode sungguhan, badan loop tertahan menunggu sesuatu (pembacaan, penerimaan dari channel, select).

Loop range

range melakukan iterasi atas sebuah koleksi dan menghasilkan satu atau dua nilai per iterasi. Apa nilainya bergantung pada apa yang di-range:

Range atasNilai pertamaNilai kedua
slice atau arrayindekselemen (salinan)
stringindeks byterune (karakter Unicode)
mapkeyvalue
channelelemen(tidak ada)
integer n (Go 1.22)0 sampai n dikurangi 1(tidak ada)
fungsi iterator (Go 1.23)apa yang dihasilkan fungsiapa yang dihasilkan fungsi

Tiga detail yang ditunjukkan output-nya:

  • Variabel nilai adalah salinan. v *= 2 di dalam loop tidak akan mengubah slice; untuk mengubah elemen, akses lewat indeks slice dengan nums[i], seperti yang dilakukan loop ketiga.
  • Indeks pada string adalah offset byte. é memakai dua byte, jadi indeksnya melompat dari 1 ke 3.
  • Urutan map acak dengan sengaja. Go mengacaknya supaya kode tidak bisa bergantung pada urutan itu. slices.Sorted(maps.Keys(m)) (Go 1.23) memberikan key secara berurutan.

range dibahas lengkap, termasuk channel, fungsi iterator, dan aturan penyalinannya, di halaman range.

break dan continue

break mengakhiri loop yang paling dalam. continue melompat ke iterasi berikutnya (dengan menjalankan post lebih dulu, di loop tiga klausa):

break dan continue Berlabel

break biasa hanya meninggalkan loop yang paling dalam. Untuk keluar dari loop luar dari dalam loop yang bersarang, beri label pada loop luar:

Label adalah identifier yang diikuti titik dua, ditaruh langsung sebelum for. Go melaporkan label yang tidak dipakai sebagai error kompilasi, sama seperti variabel yang tidak dipakai.

break di dalam switch dan select

Di dalam for, break di sebuah case switch atau select meninggalkan switch atau select, bukan loop-nya:

for {
	switch cmd := next(); cmd {
	case "quit":
		break // only exits the switch; the loop keeps running
	}
}

Pakai break berlabel, atau return, untuk meninggalkan loop dari dalam switch atau select.

Variabel Loop Sejak Go 1.22

Go 1.22 mengubah scope variabel loop: setiap iterasi sekarang mendapat salinan baru dari i dan v. Sebelumnya, satu variabel dipakai ulang untuk seluruh loop, dan itu merusak closure serta goroutine yang menangkapnya:

Dengan Go 1.22 dan sesudahnya, program ini mencetak 0 1 2 dan [aa bb cc]. Dengan semantik lama, program yang sama yang ditulis dengan for i := 0; i < 3; i++ (range atas integer belum ada sebelum 1.22) mencetak 3 3 3, dan goroutine-goroutine-nya berlomba pada i dan name yang dipakai bersama. Solusi lama, i := i di awal badan loop, sudah tidak diperlukan.

Perilakunya dipilih per modul oleh baris go di go.mod, bukan oleh versi compiler. Modul yang masih menulis go 1.21 tetap memakai semantik lama meskipun di-build dengan Go 1.24.

Kesalahan Umum

Mengubah salinannya. for _, v := range items { v.Count++ } mengubah salinan. Pakai items[i].Count++, atau lakukan range atas slice berisi pointer.

Menambahkan elemen sambil melakukan range. range mengevaluasi slice sekali saja, di awal. Elemen yang ditambahkan di dalam loop tidak dikunjungi, jadi loop tetap berakhir, tetapi tidak akan melihat item yang baru.

Menghapus dari slice berdasarkan indeks di loop yang berjalan maju. Menghapus elemen i menggeser sisanya ke kiri, sehingga elemen berikutnya terlewati. Buat slice baru, lakukan loop mundur, atau pakai slices.DeleteFunc.

Off-by-one dengan <=. for i := 0; i <= len(s); i++ membaca s[len(s)] di putaran terakhir dan panic dengan index out of range. Pakai <, atau lebih baik lagi, range.

Pekerjaan berat di dalam kondisi. Kondisi berjalan di setiap iterasi. for i := 0; i < expensiveCount(); i++ memanggil fungsi itu setiap kali; hitung sekali saja sebelum loop.

Memakai float sebagai counter. for x := 0.0; x != 1.0; x += 0.1 tidak pernah berakhir, karena 0.1 tidak punya representasi biner yang eksak. Hitung dengan integer dan hitung float-nya dari integer itu.

Pertanyaan yang sering diajukan

Bagaimana cara menulis for loop di Go?

Bentuk klasiknya punya tiga bagian yang dipisahkan titik koma, tanpa tanda kurung:

for i := 0; i < 5; i++ {
	fmt.Println(i)
}

Sejak Go 1.22, kamu juga bisa menulis for i := range 5, yang menghitung dari 0 sampai 4. Untuk menelusuri slice, pakai for i, v := range items.

Apakah Go punya while loop?

Tidak ada kata kunci while, tetapi for yang hanya berisi kondisi adalah while loop: for n > 0 { n /= 2 }. for { ... } tanpa kondisi adalah loop tak terbatas yang kamu tinggalkan dengan break atau return.

Bagaimana cara melakukan perulangan atas map di Go?

for key, value := range m { ... }. Urutan iterasinya tidak ditentukan, dan runtime mengacaknya sehingga bisa berbeda dari satu perulangan ke perulangan berikutnya. Jangan pernah mengandalkannya. Untuk urutan yang stabil, kumpulkan key-nya, urutkan dengan slices.Sort, lalu lakukan perulangan atas key yang sudah terurut.

Bagaimana cara keluar dari nested loop di Go?

Taruh label sebelum loop luar dan sebutkan label itu di break: outer: for ... { for ... { if found { break outer } } }. break biasa hanya meninggalkan for, switch, atau select yang paling dalam. continue outer juga melompat ke iterasi berikutnya dari loop yang diberi label.

Apa yang berubah pada variabel loop di Go 1.22?

Sebelum Go 1.22, for loop punya satu variabel yang dipakai bersama oleh setiap iterasi, jadi closure dan goroutine yang dijalankan di dalam loop sering kali semuanya melihat nilai terakhir. Sejak Go 1.22, setiap iterasi mendapat salinannya sendiri, jadi menangkap i atau v di dalam closure bekerja seperti yang diharapkan. Perilaku baru ini berlaku saat go.mod milik modul menulis go 1.22 atau lebih baru.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai