> For the complete documentation index, see [llms.txt](https://davidwinalda94.gitbook.io/mastering-golang/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://davidwinalda94.gitbook.io/mastering-golang/fungsi.md).

# Fungsi

Sebuah fungsi dapat memiliki dan tidak memiliki argumen. Pada contoh di bawah ini sebuah fungsi `add` yang memiliki `2` parameter bertipe `int` dan mengembalikan nilai `int`&#x20;

```go
package main

import "fmt"

func add(x int, y int) int {
	return x + y
}

func main() {
	fmt.Println(add(5, 5))
}
```

![Output program menampilkan kembalian nilai dari fungsi add()](/files/-MST1AmlvaD_f44uX1cf)

Jika dua atau lebih variabel dari parameter fungsi memiliki tipe data yang sama, maka kita bisa menggunakan cara yang lebih singkat seperti berikut ini:

```
x int, y int
```

to

```
x, y int
```

```go
package main

import "fmt"

func add(x, y int) int {
	return x + y
}

func main() {
	fmt.Println(add(5, 5))
}
```

### Multiple Results

Biasanya sebuah fungsi hanya dapat mengembalikan 1 buah nilai namun pada Go, fungsi dapat mengembalikan lebih dari 1 nilai.

```go
package main

import "fmt"

func swap(x, y string) (string, string) {
	return y, x
}

func main() {
	a, b := swap("hello", "world")
	fmt.Println(a, b)
}
```

![Fungsi swap mengembalikan dua buah nilai](/files/-MST46V7s5BuDXBprxOn)

Pada kode di atas kita melihat jika kita ingin mengembalikan nilai lebih dari 1, maka harus dideklarasikan juga tipe datanya.

### Fungsi Variadic

Go memiliki konsep **variadic function** atau pembuatan fungsi dengan parameter sejenis yang tak terbatas. Maksud **tak terbatas** disini adalah jumlah argumen yang dimasukkan ketika pemanggilan fungsi bisa berapa saja.

Parameter variadic memiliki sifat yang mirip dengan slice. Nilai dari parameter-parameter yang digunakan bertipe data sama, dan ditampung oleh sebuah variabel saja. Cara pengaksesan tiap datanya juga sama, dengan menggunakan index.

```go
package main

import "fmt"

func calculate(numbers ...int) (float64, int) {
	var total int = 0
	for _, number := range numbers {
		total += number
	}

	var avg = float64(total) / float64(len(numbers))
	return avg, total
}

func main() {
	var avg, total = calculate(5, 5, 6, 4)
	fmt.Println("Total dari hasil kalkulasi adalah", total)
	fmt.Printf("Rata-rata : %.2f\n", avg)
}
```

![Output dari fungsi calculate()](/files/-MST82eZD9eiuBMMJJzc)

Kita bisa melihat bahwa pada fungsi `calcluate` , kita dapat menggunakan banyak argumen untuk diolah di dalam fungsi tersebut.

{% hint style="info" %}
Kita bisa mengkombinasikan antara fungsi biasa dan fungsi variadic
{% endhint %}

### Pengisian Parameter Fungsi Variadic Menggunakan Data Slice <a href="#a202-pengisian-parameter-fungsi-variadic-menggunakan-data-slice" id="a202-pengisian-parameter-fungsi-variadic-menggunakan-data-slice"></a>

Kita dapat menggunakan data `slice` pada argumen fungsi variadic dengan cara menambahkan `...` di belakang nama variabel dari `slice` .

```go
package main

import "fmt"

func calculate(numbers ...int) (float64, int) {
	var total int = 0
	for _, number := range numbers {
		total += number
	}

	var avg = float64(total) / float64(len(numbers))
	return avg, total
}

func main() {
	var score = []int{2, 4, 6}
	var avg, total = calculate(score...)
	fmt.Println("Total dari hasil kalkulasi adalah", total)
	fmt.Printf("Rata-rata : %.2f\n", avg)
}
```

![Output program menampilkan hasil dari fungsi variadic berisi argumen bertipe slice](/files/-MSTA8V5-k3tFqXY7y0D)

### Fungsi Closure

Fungsi **Closure** adalah sebuah fungsi yang bisa disimpan dalam variabel. Dengan menerapkan konsep tersebut, kita bisa membuat fungsi didalam fungsi, atau bahkan membuat fungsi yang mengembalikan fungsi.

Closure merupakan *anonymous function* atau fungsi tanpa nama. Biasa dimanfaatkan untuk membungkus suatu proses yang hanya dipakai sekali atau dipakai pada blok tertentu saja.

#### Fungsi di simpan pada Variabel

Pada kode di bawah ini kita akan membuat fungsi yang akan di simpan pada sebuah variabel.

```go
package main

import "fmt"

func main() {
	var getTotal = func(numbers ...int) int {
		var total int = 0
		for _, number := range numbers {
			total += number
		}
		return total
	}

	result := getTotal(5, 5, 5)
	fmt.Println(result)
}
```

![Output dari fungsi closure](/files/-MSTDsaw6ClFf20F02Da)

Pada kode di atas kita membuat sebuah fungsi yang disimpan ke dalam variabel `getTotal` .

### Immediately-Invoked Function Expression (IIFE) <a href="#a212-immediately-invoked-function-expression-iife" id="a212-immediately-invoked-function-expression-iife"></a>

Closure jenis ini dieksekusi langsung pada saat deklarasinya. Biasa digunakan untuk membungkus proses yang hanya dilakukan sekali, bisa mengembalikan nilai, bisa juga tidak.

```go
package main

import "fmt"

func main() {
	var getTotal = func(numbers ...int) int {
		var total int = 0
		for _, number := range numbers {
			total += number
		}
		return total
	}(5, 5, 5)

	fmt.Println(getTotal)
}
```

Pada contoh di atas IIFE menghasilkan nilai balik yang kemudian ditampung `getTotal`. Perlu diperhatikan bahwa yang ditampung adalah **nilai kembaliannya** bukan body fungsi atau **closure**.

![Output program dari penggunaan IIFE](/files/-MSTDsaw6ClFf20F02Da)
