Function value memperkuat kode kita sepanjang section ini: disimpan, dikirim, dikembalikan, ditangkap closure. Namun setiap tipe di Go punya zero value, dan tipe fungsi tidak kecuali — nilainya adalah nil. Nilai fungsi nil muncul secara alami di struct field yang belum diisi, callback opsional, hingga pencarian key yang tidak ada pada map fungsi. Chapter penutup ini membahas perilaku nil pada fungsi: bentuknya, cara mengujinya, dan panik yang menanti pemanggil yang lupa memeriksa.
Zero Value Tipe Fungsi #
Variabel bertipe fungsi yang dideklarasikan tanpa nilai awal otomatis berisi nil, sama seperti pointer yang belum menunjuk apa pun:
var f func() int // zero value function adalah nil.
fmt.Println("f == nil:", f == nil)
fmt.Printf("Tipe f: %T\n", f)Pengujian f == nil adalah satu-satunya perbandingan yang sah untuk nilai fungsi. Kompilator menolak pembandingan dua fungsi dengan pesan func can only be compared to nil — dua fungsi dengan isi identik pun tidak bisa dinyatakan sama. Verb format %T tetap menampilkan tipe func() int meskipun nilainya nil, karena tipe dan isi variabel adalah dua hal terpisah.
Memanggil nil: Program Panic #
Pemanggilan f() saat f bernilai nil tidak ditolak kompiler — galatnya muncul saat runtime. Berkas error-nil-func.go di bawah sengaja memanggil fungsi bernilai nil untuk membuktikannya:
package main
import "fmt"
func main() {
var f func() int = nil
fmt.Println("Memanggil fungsi bernilai nil...")
f()
}Output yang Dihasilkan:
Memanggil fungsi bernilai nil...
panic: runtime error: invalid memory address or nil pointer dereferenceRuntime menghentikan program dengan panic nil pointer dereference karena tidak ada kode yang bisa dieksekusi. Setelah dua baris di atas, go run masih mencetak baris sinyal SIGSEGV, stack trace, dan exit status 2 — baris-baris itu memuat alamat memori dan path yang berbeda tiap komputer, sehingga tidak kita salin utuh. Ingat selalu frasa ini: program panic, program berhenti total.
Pola Pemeriksaan Sebelum Memanggil #
Pola penangkalnya sederhana: periksa f == nil sebelum memanggil, lalu beri jalur default. Fungsi jalankan berikut menerima callback opsional dan menggantinya dengan nilaiDefault saat callback tidak diisi:
// jalankan menjalankan f dengan aman: nilai nil diganti nilaiDefault.
func jalankan(f func() int) int {
if f == nil {
fmt.Println("f bernilai nil, memakai fungsi bawaan")
return nilaiDefault()
}
return f()
}Dua cabang itu menghasilkan pemanggilan yang selalu aman: jalankan(nil) menempuh jalur default, jalankan(tujuh) mengeksekusi callback aslinya. Pola yang sama bekerja untuk parameter opsional pada struct konfigurasi — si pengonsumsi boleh tidak mengisi field callback, dan pemanggilan selalu melewati pemeriksaan nil lebih dulu.
Program Utuh #
Berkas function-nil-demo.go menunjukkan zero value, verb %T, dan pola pemeriksaan dalam satu program. Jalankan dari direktori chapter:
go run function-nil-demo.goOutput yang Dihasilkan:
f == nil: true
Tipe f: func() int
f bernilai nil, memakai fungsi bawaan
jalankan(nil) = 42
jalankan(tujuh) = 7Mari kita telaah baris demi baris program di atas:
- Baris 16 (
func jalankan(f func() int) int): menerima callback yang boleh berupanil— kontrak opsional di tanda tangannya. - Baris 17–20 (
if f == nil { ... }): cabang pemeriksaan yang mengganti callback kosong dengannilaiDefault()sebelum ada pemanggilan berisiko. - Baris 21 (
return f()): pemanggilan callback asli yang dijamin aman karena sudah lolos pemeriksaan. - Baris 25 (
var f func() int): deklarasi tanpa nilai — zero value tipe fungsi adalahnil, terbukti darif == nil: true. - Baris 27 (
fmt.Printf("Tipe f: %T\n", f)): verb%Tmenampilkan tipe fungsi lengkapfunc() intmeskipun isinyanil.
Kita kini menutup section Fungsi dengan perlengkapan lengkap: deklarasi, parameter, nilai kembalian berganda, variadic, fungsi sebagai nilai, closure, recursion, hingga pengaman nil. Struktur data Go siap menjadi tahap berikutnya — dimulai dari kumpulan nilai berurut pada section Array, Slice, dan Map
.
Referensi #
- Function types — Go Spec
— tipe fungsi dan nilainya
nil. - Package fmt
— verb
%Tuntuk menampilkan tipe. - Frequently Asked Questions — Go — latar perilaku tipe dan zero value.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
error-nil-func.go
Unduh berkaspackage main
import "fmt"
func main() {
var f func() int = nil
fmt.Println("Memanggil fungsi bernilai nil...")
f()
}
function-nil-demo.go
Unduh berkaspackage main
import "fmt"
// nilaiDefault dipakai saat callback tidak diisi.
func nilaiDefault() int {
return 42
}
// tujuh adalah contoh fungsi konkrit yang siap dipakai sebagai callback.
func tujuh() int {
return 7
}
// jalankan menjalankan f dengan aman: nilai nil diganti nilaiDefault.
func jalankan(f func() int) int {
if f == nil {
fmt.Println("f bernilai nil, memakai fungsi bawaan")
return nilaiDefault()
}
return f()
}
func main() {
var f func() int // zero value function adalah nil.
fmt.Println("f == nil:", f == nil)
fmt.Printf("Tipe f: %T\n", f)
fmt.Println("jalankan(nil) =", jalankan(nil))
fmt.Println("jalankan(tujuh) =", jalankan(tujuh))
}