# 3. Tipe Komposit ## 3.1 Array Seperti bahasa pemrograman lain, Go mempunyai array. Namun, array jarang digunakan dalam Go. Kita akan mempelajari kenapa dalam sesaat, tetapi pertama kita akan membahas secara cepat syntax deklarasi array dan penggunaannya. Semua elemen-elemen dalam array harus tipe yang ditentukan (ini tidak berarti elemen-elemen harus dalam tipe yang sama). Terdapat beberapa variasi deklarasi. Pertama, kita menentukan ukuran array dan tipe dari elemen-elemen dalam array: ```go var x [3]int ``` Deklarasi di atas membuat sebuah array dari tiga `int`. Karena tidak ada nilai yang ditetapkan, semua posisi(`x[0]`, `x[1]`, dan `x[2]`) diinisialisasi ke nilai nol untuk `int`, yang berarti 0. Jika kita mepunyai nilai awal untuk array, kita dapat menetapkannya dengan literal array: ```go var x = [3]int{10, 20, 30} ``` Jika kita mempunyai array *sparse* (sebuah array yang kebanyakan elemennya ditetapkan dengan nilai nol), kita dapat menetapkan hanya indeks-indeks tertentu saja yang mempunyai nilai dalam literal array: ```go var x = [12]int{1, 5: 4, 6, 10: 100, 15} ``` Statement di atas membuat sebuah array dengan 12 `int` dengan nilai berikut: `[1, 0, 0, 0, 0, 4, 6, 0, 0, 0, 100, 15]`. Ketika menggunakan sebuah lieteral array untuk menginisialisasi array, kita dapat menggantikan ukuran array dengan menggunakan `...`: ```go var x = [...]int{10, 20, 30} ``` Kita dapat menggunakan `==` dan `!=` untuk membandingkan array: ```go var x = [...]int{1, 2, 3} var y = [3]int{1, 2, 3} fmt.Println(x == y) // Mencetak true ``` Go hanya mempunyai array satu diomensi, tetapi kita dapat mensimulasikan array multidimensi: ```go var x [2][3]int ``` Ini mendeklarasikan `x` sebagai sebuah array dengan panjang 2 yang tipe elemennya adalah sebuah array `int` dengan panjang 3. ## 3.2 Slice Slice berbeda dari array karena panjang dari slice bukan merupakan bagian dari tipe dari slice. Ini menghilangkan limitasi dari array. Kita dapat menulis sebuah fungsi tungggal yang memroses slice dari ukuruan berapapun (kita akan membahas fungsi pada Bab 5), dan kita dapat menambahkan elemen-elemen slice setiap saat diperlukan. Setelah kita membahas dasar-dasar penggunaan slice dalam Go, kita akan bahas cara terbaik untuk menggunakannya. Bekerja dengan slice mirip dengan bekerja dengan array, tetapi terdapat sedikit perbedaan. Hal pertama yang perlu diperhatikan bahwa kita tidak menetapkan ukuran dari slice ketika kita mendeklarasikannya: ```go var x = []int{10, 20, 30} ``` Statement di atas membuat sebuah slice dengan 3 `int` menggunakan literal slice. Seperti array kita dapat menentukan indeks dengan nilai-nilai dalam literal slice: ```go var x = []int{1, 5: 4, 6, 10: 100, 15} ``` Ini akan membuat sebuah slice dari 12 `int` dengan nilai-nilai berikut: `[1, 0, 0, 0, 4, 6, 0, 0, 0, 100, 15]`. Kita dapat mensimulasikan slice multidimensi dengan membuat slice berisi slice: ```go var x [][]int ```` Kita dapat membaca dan menulis slice menggunakan syntax bracket, dan, seperti array, kita tidak dapat membaca atau menulis setelah akhir atau menggunakan indeks negatif. ```go x[10] = 10 fmt.Println(x[2]) ``` Sejauh ini slice terlihat identik dengan array. Kita memulai melihat perbedaan array dan slice ketika kita melihat cara pendeklarasian slice tanpa menggunakan lieteral: ```go var x []int ``` Ini membuat sebuah slice dari `int`. Karena tidak ada nilai ditugaskan, `x` ditugaskan dengan nilai nol untuk slice: `nil`. Kita akan membahas lebih lanjut mengenai `nil` pada Bab 6. Hal yang perlu ktia ketahui saat ini adalah `nil` sedikit berbeda dari `null` pada bahasa pemrograman lain. Dalam Go, `nil` adlah sebuah identifier yang merepresentasikan ketiadaan nilai untuk suatu tipe. Seperti konstan numerik tanpa tipe yang kita lihat pada bab sebelumnya, `nil` tidak mempunyai tipe, sehingga ia dapat ditugaskan atau dibandingkan dengan nilai-nilai dari tipe-tipe berbeda. Slice `nil` tidak berisi apapun. Sebuah slice adlah tipe pertama yang kita lihat yang tidak dapat dibandingkan. Kita akan mendapatkan compile-time error ketika menggunakan `==` untuk melihat apakah dua slice identik atu menggunakan `!=` untuk melihat apakah kedua slice berbeda. Hal yang bisa kita lakukan untuk membandingkan sebuah slice adalah dengan `nil`: ```go fmt.Println(x == nil) // prints true ``` ### `len` Go menyediakan sejumlah fungsi-fungsi built-in untuk bekerja dengan tipe-tipe built-in. Kita telah melihat fungsi built in `complex`, `real`, dan `imag` untuk membuat dan mengekstrasi angka kompleks. Terdapat sejumlah fungsi-fungsi built-in untuk slice juga. Kita telah melihat fungsi `len` ketika membahas array. Fungsi `len` juga bekerja untuk slice, dan ketika kita memberikan slice `nil` ke `len`, fungsi tersebut akan mengembalikan 0. ### `append` Fungsi built-in `append` digunakan untuk membesarkan slice: ```go var x []int x = append(x, 10) ``` Fungsi `append` menerima setidaknya dua parameter, sebuah slice dari tipe apapun dan sebuah nilai dari tipe yang sama. Fungsi ini mengembalikan sebuah slice dari tipe yang sama. Slice yang dikembalikan ditungaskan kembali ke slice yang diberikan. Pada contoh ini, kita menamabahkan nilai 10 ke slice `nil`, tetapi kita juga dapat meng-append slice yang mempunyai elemen: ```go var x = []int{1, 2, 3} x = append(x, 4) ``` Kita dapat meng-append lebih dari satu nilai: ```go x = append(x, 5, 6, 7) ``` Slice lain dapat di-append ke suatu slice menggunakan operator `...` untuk mengekspansi slice sumber menjadi nilai-nilai individo (kita akan membahas lebih lanjut mengenai operator `...` pada pembahasan Variadic Input Parameters): ```go y := []int{20, 30, 40} x = append(x, y...) ``` Kita akan mendapatkan error compile-time jika kita lupa menugaskan nilai yang dikembalikan `append`. ### Kapasitas Kita telah melihat bahwa slice adalah sebuah barisan nilai-nilai. Setiap elemen dalam slice ditungaskan ke lokasi memori berdampingan, yang membuatnya dapat secara cepat ditulis dan dibaca. Setiap slice mempunyai kapasitas, yang merupakan banyaknya lokasi memori berdampingan yang direservasi. Ini dapat lebih besar dari panjang slice. Setiap kali kita meng-append ke slice, satu atau lebih nilai-nilai ditambahkan ke akhir dari slice. Setiap nilai yang ditambahkan memperbesar panjang slice sebesar 1 unit. Keteka panjang tersebut mencapai kapasitas, tidak ada lagi tempat untuk menaruh nilai baru. Jika kita menambahkan nilai ketika panjang sama dengan kapasitas, fungsi `append` menggunakan runtime Go untuk mengalokasikan slice baru dengan kapasitas lebih besar. Nilai-nilai dalam slice original disalin ke slice baru, nilai-nilai baru ditambahkan di akhir, dan slice baru dikembalikan. > Run Time Go > Setiap bahasa pemrograman high-level bergantung pada set library yang memungkinkan program ditulis dalam bahasa tersebut berjalan, dan Go juga seperti itu. Runtime Go menyediakan layanan seperti alokasi memori dan garbage collection, dukungan concurrency, networking, dan implementasi tipe built in dan fungsi. .... ## Map Slice berguna ketika kita mempunyai data sekuensial. Seperti kebanyakan bahasa, Go menyediakan tipe data built in untuk situasi dimana kita memerlukan asosiasi satu nilai ke nilai lain. Tipe map ditulis sebagai `map[keyType]valueType`. Mari kita lihat beberapa cara untuk mendeklarasikan map. Pertama, kita dapat menggunakan deklarasi `var` untuk membuat variabel map yang ditetapkan ke nilai nol: ```go var nilMap map[string]int ``` Pada contoh di atas, `nilMap` dideklarasikan sebagai sebuah map dengan key `string` dan nilai `int`. Nilai nol untuk sebuah map adalah `nil`. Map `nil` mempunyai panjang 0. Usaha untuk membaca map `nil` akan selalu mengemablikan nilai nol untuk tipe nilai map. Namun, mencoba menulis ke variabel map `nil` menyebabkan panic. Kita dapat menggunakan deklarasi `:=` untuk membuat sebuah variabel map dengan menugaskannya dengan sebuah map literal: ```go totalWins := map[string]int{} ``` Dalam kasus ini, kita menggunakan literal map kosong. Ini tidak sama de4ngan map `nil`. Map ini mempunyai panjang 0, tetapi kita dapat membaca dan menulis ke map yang ditugaskan dengan literal map kosong. Map nonempty: ```go tim := map[string][]string { "Orcas": []string{"Fred", "Ralph", "Bijou"}, } ```