Sejauh ini fungsi hanya kita panggil lewat namanya. Padahal di Go, fungsi adalah warga kelas satu (first-class): fungsi punya tipe, bisa disimpan ke variabel, dikirim sebagai argumen, dan dikembalikan dari fungsi lain — persis seperti int atau string. Kemampuan ini adalah fondasi gaya pemrograman yang memperlakukan perilaku sebagai data: callback, strategi yang dipilih saat runtime, hingga mesin pembangkit fungsi. Pada chapter ini kita akan mempraktikkan ketiga peran tersebut satu per satu, dan di ujungnya menemukan pintu menuju closure.

Fungsi sebagai Nilai #

Nama fungsi tanpa tanda kurung adalah nilai fungsi. Penugasan f := double tidak memanggil double; penugasan tersebut menyalin referensi fungsi ke variabel f yang kini bertipe func(int) int. Pemanggilan baru terjadi ketika kurung dan argumen ditambahkan:

go
f := double
fmt.Println("f(8) =", f(8))

Tanda kurung adalah pembeda pentingnya: double berarti nilai fungsinya, double(8) berarti hasil eksekusinya. Nilai fungsi bisa ditaruh di mana saja — di variabel, di elemen slice, di field struct — dan tetap dipanggil dengan cara yang sama.

Tipe Fungsi Bernama #

Tipe fungsi ditulis dengan kata func diikuti tanda kurung parameter dan tipe kembalian, misalnya func(int) int — “fungsi yang menerima satu int dan mengembalikan int”. Tanda tangan yang panjang tentu merepotikan, maka Go mengizinkan kita memberi nama alias lewat deklarasi type:

go
// Operation mendefinisikan tipe fungsi yang menerima dan mengembalikan int.
type Operation func(int) int

Kedua fungsi kita, double dan addOne, kini berharga tipe Operation secara otomatis karena tanda tangannya cocok — tidak perlu konversi apa pun. Signature yang sama berarti tipe yang sama; signature berbeda berarti tipe berbeda.

Mengirim Fungsi sebagai Argumen #

Parameter bertipe fungsi menerima nilai fungsi dari pemanggil, dan badan fungsi tinggal memanggilnya. Fungsi apply berikut menjalankan fungsi apa pun bertipe Operation terhadap satu nilai:

go
// apply menjalankan fungsi f terhadap nilai v.
func apply(f Operation, v int) int {
	return f(v)
}

Satu apply sekarang melayani semua operasi: apply(double, 5) menghasilkan 10 dan apply(addOne, 5) menghasilkan 6. Inilah pola callback yang kita temui di standard library — misalnya komparator pada slices.SortFunc — dan di hampir seluruh API Go modern.

Mengembalikan Fungsi dari Fungsi #

Peran ketiga: fungsi boleh membangun dan mengembalikan fungsi baru. makeMultiplier menerima factor lalu menghasilkan fungsi pengali yang menyimpan faktor tersebut di dalam dirinya:

go
// makeMultiplier mengembalikan fungsi pengali dengan faktor tertentu.
func makeMultiplier(factor int) Operation {
	return func(x int) int {
		return x * factor
	}
}

Pemanggilan kaliTiga := makeMultiplier(3) menghasilkan fungsi siap pakai; kaliTiga(7) mengembalikan 21. Tiga peran nilai fungsi dirangkum pada tabel berikut:

PeranBentukHasil
Disimpanf := doubleVariabel bertipe func(int) int
Dikirimapply(double, 5)Callback dijalankan di dalam apply
DikembalikanmakeMultiplier(3)Fungsi baru yang terikat faktor 3

Program Utuh #

Berkas first-class-demo.go mengeksekusi ketiga peran dalam satu program. Jalankan dari direktori chapter:

bash
go run first-class-demo.go

Output yang Dihasilkan:

text
f(8) = 16
apply(double, 5) = 10
apply(addOne, 5) = 6
kaliTiga(7) = 21

Mari kita telaah baris demi baris program di atas:

  1. Baris 6 (type Operation func(int) int): mendeklarasikan alias tipe untuk seluruh fungsi satu-masukan-satu-keluaran bertipe int.
  2. Baris 19 (func apply(f Operation, v int) int): menerima nilai fungsi sebagai parameter lalu menjalankannya dengan f(v).
  3. Baris 24 (func makeMultiplier(factor int) Operation): tipe kembalian berupa fungsi — apply dan makeMultiplier memperlakukan fungsi sebagai data.
  4. Baris 25–27 (return func(x int) int): membangun fungsi tanpa nama yang menangkap factor dari lingkungan makeMultiplier.
  5. Baris 30–39 (isi main): menugaskan f := double, mengirim double dan addOne ke apply, lalu memanggil hasil makeMultiplier(3).

Fungsi pengali yang keluar dari makeMultiplier membuktikan bahwa fungsi bisa lahir dari fungsi lain. Pertanyaan berikutnya sudah menggantung: bagaimana factor bertahan setelah makeMultiplier selesai? Jawabannya — closure — adalah chapter berikutnya.

Referensi #

Berkas Sumber

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

first-class-demo.go

Unduh berkas
go
package main

import "fmt"

// Operation mendefinisikan tipe fungsi yang menerima dan mengembalikan int.
type Operation func(int) int

// double menggandakan nilai masukan.
func double(x int) int {
	return x * 2
}

// addOne menambah satu pada nilai masukan.
func addOne(x int) int {
	return x + 1
}

// apply menjalankan fungsi f terhadap nilai v.
func apply(f Operation, v int) int {
	return f(v)
}

// makeMultiplier mengembalikan fungsi pengali dengan faktor tertentu.
func makeMultiplier(factor int) Operation {
	return func(x int) int {
		return x * factor
	}
}

func main() {
	f := double
	fmt.Println("f(8) =", f(8))

	fmt.Println("apply(double, 5) =", apply(double, 5))
	fmt.Println("apply(addOne, 5) =", apply(addOne, 5))

	kaliTiga := makeMultiplier(3)
	fmt.Println("kaliTiga(7) =", kaliTiga(7))
}