Function
Sampai saat ini kita telah menggunakan fungsi berupa main() yakni block building (function) yang dieksekusi pertama kali oleh golang. Bisa dikatakan sebagai suatu bootstrap. Pada golang nama lain dari fungsi adalah procedure ataupun subroutine. Ketigannya memiliki makna yang sama.
Membuat fungsi
1. Fungsi tanpa parameter dan return
Untuk membuat fungsi secara basic/dasar format yang perlu diperhatikan adalah
func nama_fungsi
fungsi ini tidak memiliki parameter yang dibutuhkan ataupun suatu return. Contoh dari implementasi fungsi berdasarkan format diatas adalah sebagai berikut ini
package main import ( "fmt" ) func main() { tulisNama() } func tulisNama() { fmt.Println("degananda ferdian priyambada") }
untuk memanggil fungsi tersebut dimain (agar fungsi yang kita buat dieksekusi oleh program karena main() adalah suatu bootstrap) maka panggil fungsi tersebut di bagian main() dengan cara menuliskan nama fungsi ditambah kurung buka dan kurung tutup -> “namafungsi()”
2. Fungsi dengan parameter dan nilai return
Kali ini kita akan membuat suatu fungsi yang membutuhkan parameter dan nilai return. kasusnya adalah membuat fungsi untuk merata-rata (average) nilai ujian yang tersimpan dalam suatu array. Format penulisan fungsinnya adalah sebagai berikut ini
func nama_fungsi(parameter tipedata) nilaireturn tipedata
Parameter yang kita gunakan dapat lebih dari satu begitupula dengan nilai returnnya. Kita dapat memberikan lebih dari satu nilai return jika memang dibutuhkan. Simak kode dibawah ini untuk mengimplmenetasikan format membuat fungsi diatas
package main import ( "fmt" ) func main() { nilaiUjian := []int{21, 52, 63, 74, 25, 86, 77, 58, 89, 101} fmt.Println(averageNilaiUjian(nilaiUjian)) } func averageNilaiUjian(nilaiUjian []int) float32 { var total int for _, value := range nilaiUjian { total += value } return float32(total) / float32(len(nilaiUjian)) }
parameter yang dibutuhkan oleh fungsi diatas adalah nilaiUjian dengan tipe array yang memiliki anggota berupa int(integer) dan mereturn float32.
Casting
Permasalahannya disini adalah nilai yang kita jumlahkan bertipe integer , panjang dari array pun bertipe integer sedangkan nilai return yang kita definisikan adalah float. Maka kita perlu melakukan casting pada total nilai dan panjang dari array agar menghasilkan float.
Proses konversi tipedata tersebut biasa disebut dengan casting.
3. Function stack
Stack adalah tumpukan. Kita dapat menumpuk fungsi-fungsi yang kita buat sehingga membuat suatu urutan eksekusi yang mana setiap fungsi saling berhubungan. hal ini dinamakan sebagai function stack dalam golang. Contohnya kita akan membuat fungsi yang menentukan rata-rata nilai tersebut telah memenuhi KKM(>=75) yang berarti lulus atau jika tidak memenuhi KKM maka tidak lulus.
Perhatikan kode dibawah ini
package main func main() { nilaiUjian := []int{21, 52, 63, 74, 25, 86, 77, 58, 89, 101} averageNilaiUjian(nilaiUjian) } func apakahLulus(nilai float32) (float32, bool) { if nilai >= 75 { return nilai, true } else { return nilai, false } } func averageNilaiUjian(nilaiUjian []int) { var total int for _, value := range nilaiUjian { total += value } apakahLulus(float32(total) / float32(len(nilaiUjian))) }
stacknya adalah seperti beriktu
- pertama main memanggil fungsi averageNilaiUjian dengan input parameter berupa array dari nilai
- selanjutnya pada fungsi averageNilaiUjian melakukan komputasi
- setelah hasil komputasi melakukan perhitungan rata-rata nilai maka hasilnya digunakan untuk memanggil/invoke fungsi apakahLulus untuk menentukan nilai tersebut melebihi kkm dan lulus ataupun tidak.
itulah yang dinamakan dengan function stack, yakni memanggil beberapa fungsi secara bertumpuk. Nilai return yang lebih dari satu kita letakan dalam (return1, return2, return3, dan seterusnya).
4. Return dengan nama
kita dapat memberikan nama layaknya suatu variable pada nilai return dalam suatu fungsi. Perhatikan contoh dibawah ini
package main import ( "fmt" ) func main() { nilaiUjian := []int{21, 52, 63, 74, 25, 86, 77, 58, 89, 101} fmt.Println(averageNilaiUjian(nilaiUjian)) } func averageNilaiUjian(nilaiUjian []int) (rataRata float32) { var total int for _, value := range nilaiUjian { total += value } rataRata = float32(total) / float32(len(nilaiUjian)) return }
Variadic function
Jika anda memiliki input parameter dalam suatu fungsi yang merupakan deret maka anda dapat menggunakan variadic function ini. Meski juga dapat dilakukan dengan menggunakan parameter berupa array. Perhatikan contoh dibawah ini
package main import ( "fmt" ) func main() { fmt.Println(averageNilaiUjian(1, 2, 3, 4, 5)) } func averageNilaiUjian(nilaiUjian ...int) (rataRata float32) { var total int for _, value := range nilaiUjian { total += value } rataRata = float32(total) / float32(len(nilaiUjian)) return }
Input yang kita tuliskan pada parameter seperti layaknya menulis literal. Namun oleh fungsi tersebut diproses layaknya suatu array. Sehingga fungsi loop dengan range masih tetap berjalan. Simbol “…” inilah yang menjadikan parameter tersebut seperti “array” yang ditulis secara literal. Mekanisme seperti inilah yang disebut sebagai variadic function dalam golang.
Closure
Function yang mereturn function lainnya. Mekanisme seperti ini disebut sebagai closure. Contohnya disini kita memiliki variable rataRataNilai yang didalamnya terdapt fungsi yang mereturn hasil komputasi average.
package main import ( "fmt" ) func main() { nilaiUjian := []int{21, 52, 63, 74, 25, 86, 77, 58, 89, 101} hitungAverage := func(nilaiUjian []int) float32 { var total int for _, value := range nilaiUjian { total += value } return float32(total) / float32(len(nilaiUjian)) } fmt.Println(hitungAverage(nilaiUjian)) }
inilah yang disebut dengan closure. Fungsi yang tersimpan dalam suatu variable. Lalu apa perbedaan dengan mendefinisikan fungsi diluar variable ? jawabannya adalah akses terhadap lokal variabel. Perhatikan kode dibawah ini. Variable nilaiUjian akan diakses secara langsung yang tidak lagi menjadi suatu parameter
package main import ( "fmt" ) func main() { nilaiUjian := []int{21, 52, 63, 74, 25, 86, 77, 58, 89, 101} hitungAverage := func() float32 { var total int for _, value := range nilaiUjian { total += value } return float32(total) / float32(len(nilaiUjian)) } fmt.Println(hitungAverage()) }
dengan closure kita dapat mengakses local variable yang berada didalam fungsi tersebut.
Rekursi
Mungkin anda telah familiar dengan rekursi yakni fungsi yang memanggil dirinnya sendiri. Contohnya seperti berikut ini
func factorial(x uint) uint { ifx==0{ return 1 } return x * factorial(x-1) }
fungsi diatas akan menghitung nilai faktorial. Kita menggunakan unit (unsigned integer) karena input harus berupa bilangan positif. Integer atau signed integer dapat menampung bilangan negatif dan positif oleh karena itu uint dipilih sebagai tipedata untuk parameter.