Apps Artificial Intelligence CSS DevOps Go JavaScript Laravel Linux MongoDB MySQL PHP Python Rust Vue

Beberapa Cara Menangani Parameter Opsional di Go

2 min read .
Beberapa Cara Menangani Parameter Opsional di Go

Satu hal yang bikin Go beda dari bahasa lain adalah kesederhanaannya. Go nggak punya fitur parameter opsional seperti Python atau JavaScript. Jadi kalau bikin fungsi, kita harus eksplisit soal apa aja parameternya.

Tapi bukan berarti kita nggak bisa bikin fungsi yang fleksibel. Ada beberapa pola yang biasa dipakai developer Go untuk “menyiasati” parameter opsional. Yuk kita lihat satu per satu.

1. Variadic Parameter

Cara paling gampang adalah pakai variadic parameter (...). Dengan ini, sebuah fungsi bisa nerima argumen dengan jumlah yang nggak pasti.

func greet(message string, names ...string) {
	for _, name := range names {
		fmt.Printf("%s, %s!\n", message, name)
	}
}

func main() {
	greet("Hello")
	greet("Hello", "Alice", "Bob", "Charlie")
}

message wajib ada, sedangkan names bisa kosong, satu, atau banyak.

2. Struct Sebagai Config

Kalau butuh fleksibilitas lebih, bikin aja struct untuk nampung parameter opsional. Dengan gini, kita bisa kasih default value atau validasi.

type GreetOptions struct {
	Message string
	Names   []string
}

func greet(options GreetOptions) {
	for _, name := range options.Names {
		fmt.Printf("%s, %s!\n", options.Message, name)
	}
}

func main() {
	greet(GreetOptions{Message: "Hello", Names: []string{"Alice", "Bob"}})
	greet(GreetOptions{Message: "Hi", Names: []string{"Charlie"}})
}

Struct ini bisa diisi sesuai kebutuhan. Kalau butuh default, tinggal set saat bikin instance.

3. Functional Options

Ini pola yang cukup populer di komunitas Go, apalagi buat konfigurasi yang kompleks. Caranya: bikin fungsi kecil (option) yang ngubah config utama.

type GreetOptions struct {
	Message string
	Names   []string
}

type Option func(*GreetOptions)

func WithMessage(message string) Option {
	return func(o *GreetOptions) {
		o.Message = message
	}
}

func WithNames(names ...string) Option {
	return func(o *GreetOptions) {
		o.Names = names
	}
}

func greet(options ...Option) {
	opts := GreetOptions{
		Message: "Hello",
		Names:   []string{"World"},
	}

	for _, o := range options {
		o(&opts)
	}

	for _, name := range opts.Names {
		fmt.Printf("%s, %s!\n", opts.Message, name)
	}
}

func main() {
	greet()
	greet(WithMessage("Hi"), WithNames("Alice", "Bob"))
}

Awalnya greet punya default config, lalu tiap option bisa dipakai buat override. Rapi banget kalau parameternya banyak.

4. Chained Config (Fluent Style)

Kalau mau gaya yang lebih “builder pattern”, bisa bikin struct dengan method yang di-chain.

type GreetConfig struct {
	Message string
	Names   []string
}

func NewGreetConfig() *GreetConfig {
	return &GreetConfig{
		Message: "Hello",
		Names:   []string{"World"},
	}
}

func (gc *GreetConfig) SetMessage(message string) *GreetConfig {
	gc.Message = message
	return gc
}

func (gc *GreetConfig) SetNames(names ...string) *GreetConfig {
	gc.Names = names
	return gc
}

func (gc *GreetConfig) Greet() {
	for _, name := range gc.Names {
		fmt.Printf("%s, %s!\n", gc.Message, name)
	}
}

func main() {
	NewGreetConfig().
		SetMessage("Hi").
		SetNames("Alice", "Bob").
		Greet()
}

Hasilnya mirip parameter bernama, walaupun Go sendiri nggak punya fitur itu.

Kesimpulan

Go memang nggak punya parameter opsional bawaan, tapi ada banyak cara buat ngakalinnya:

  • Variadic: simpel buat argumen yang fleksibel.
  • Struct: jelas dan bisa kasih default.
  • Functional options: scalable kalau parameternya banyak.
  • Builder style: enak dibaca kalau konfigurasi panjang.

Pilih aja sesuai kebutuhan. Nggak ada yang benar/ salah—semua soal trade-off dan konteks.

Lihat Juga

chevron-up