Pada artikel sebelumnya kita telah belajar apa itu type assertions dan cara penggunaannya pada bahasa pemrogaman go atau golang. apabila anda belum mengikuti artikel sebelumnya saya sarankan anda untuk membaca artikel sebelumnya tentang Golang – Pengenalan dan cara menggunakan type assertions. Dan artikel kali ini kita akan belajar tentang pointer dan cara menggunakannya pada bahasa pemrogaman go.
Pengenalan pass by value
Secara default di golang selalu menggunakan pass by value atau istilahnya passing data by value. Artinya jika kita mengirim sebuah variable ke dalam function, method atau variable lain, sebenarnya yang dikirim adalah duplikasi dari value nya. Untuk lebih jelasnya perhatikan contoh berikut.
Pertama kita akan membuat baris kode sederhana seperti berikut
package main
import "fmt"
type Address struct {
City, Provience, Country string
}
func main() {
address1 := Address{"Subang", "Jawa Barat", "Indonesia"}
address2 := address1
address2.City = "Bandung"
fmt.Println(address1)
fmt.Println(address2)
}

Pada kode diatas kita membuat struct dengan nama Address
kemudian kita juga membuat variable address1
dari struct dengan data Subang, Jawa Barat, Indonesia
, selanjutnya kita membuat variable address2
yang me refer ke address1
. Terakhir kita merubah data City
pada address2
menjadi Bandung
. Sekarang coba jalankan kode diatas.

Dari output di atas dapat dilihat jika data City
pada address1
tidak berubah, nah jika sebelumnya anda telah belajar pemrogaman java atau php maka anda akan sedikit bingung kenapa data address1
tidak berubah, nah pada golang memang seperti ini karena data nya benar-benar di copy.
Jadi jika kasus nya seperti diatas maka yang terjadi sebenarnya seperti berikut.

Saat kita membuat variable address1
maka dalam memory penyimpanan kita akan menyimpan data Address1
kemudian saat kita meng assign address2 := address1
maka yang sebenarnya terjadi adalah di dalam memory akan meng copy data dari address1
dan membuat data baru address2
inilah kenapa jika kita merubah data address2
maka address1
tidak akan berubah karena di dalam memory memang sudah bukan data yang sama lagi tapi 2 data yang berbeda.
Pointer
Pointer adalah kemampuan untuk membuat reference ke lokasi data di memory yang sama, tanpa menduplikasi data yang sudah ada. Atau sederhananya dengan kemampuan pointer kita bisa membuat pass by reference, jadi pass by reference adalah kebalikan dari pass by value, jika pass by value akan menduplikat data dan dikirim ke tempat lain maka pass by reference data nya tetap pada lokasi yang sama.

Jadi jika kita melakukan pass by reference dengan pointer maka hasilnye seperti gambar di atas. Jadi saat kita membuat address2
dari address1
maka dia akan mengacu ke data di memory yang sama, oleh karena itu saat kita merubah data address2
maka data pada address1
juga akan ikut berubah.
Operator &
Jadi bagaimana cara kita melakukan pointer di golang, untuk membuat sebuah variable dengan nilai pointer ke variable yang lain, kita bisa menggunakan operator &
di ikuti dengan nama variable nya. Contohnya seperti berikut
package main
import "fmt"
type Address struct {
City, Provience, Country string
}
func main() {
address1 := Address{"Subang", "Jawa Barat", "Indonesia"}
address2 := &address1
address2.City = "Bandung"
fmt.Println(address1)
fmt.Println(address2)
}

Jadi jika kita anda ingin membuat address2
yamg mana akan pointer ke address1
maka anda jangan hanya menggunakan address1
pada saat deklarasi address2
tetapi gunakan juga operator &
sebelum nama variable nya, seperti &address1
. Dengan begini kita memberitahu jika saat ini address2
akan me refer ke address1
.
Nah jika saat ini kita merubah data City
pada address2
maka data di duavariable tersebut akan ikut berubah, karena saat ini address2
sebenarnya adalah pointer ke address1
. Berikut output nya jika kode dijalankan

Perhatikan output di atas, dapat dilihat jika saat ini kedua variable teah berubah datanya, dan jika di perhatikan lebih lanjut terdapat sedikit perbedaan pada outputnya. Saat kita melakukan print address1
maka akan tampil data seperti biasa nya tetapi pada address2
terdapat &
di depan datanya, nah ini menunjukkan jika sebenarnya address2
adalah pointer.
Pada contoh diatas kita membuat variable secara singkat, sebenarnya jika kita membuat variable beserta tipe datanya maka akan seperti berikut.
package main
import "fmt"
type Address struct {
City, Provience, Country string
}
func main() {
var address1 Address = Address{"Subang", "Jawa Barat", "Indonesia"}
var address2 *Address = &address1
address2.City = "Bandung"
fmt.Println(address1)
fmt.Println(address2)
}

Pada deklarasi variable bisa dilihat jika terdapat perbedaan tipe data yang mana pada address2
deklarasi nya terdpat operator *
lebih tepatnya *Address
.
Operator *
Saat kita merubah data variable pointer, maka yang berubah hanya variable tersebut. Semua data yang mengacu ke data yang sama tidak akan berubah, jika kita ingin merubah seluruh variable yang mengacu ke data tersebut maka kita bisa menggunakan operator *
. Berikut contohnya
package main
import "fmt"
type Address struct {
City, Provience, Country string
}
func main() {
var address1 Address = Address{"Subang", "Jawa Barat", "Indonesia"}
var address2 *Address = &address1
address2.City = "Bandung"
address2 = &Address{"Malang", "Jawa Timur", "Indonesia"}
fmt.Println(address1)
fmt.Println(address2)
}

Pada contoh kode diatas masih sama address2
adalah pointer ke address1
tetapi pada baris 15 kita merubah isi variable addrress2
dengan tetap pointer ke Address
tetapi menggunakan data baru. Nah jika seperti ini maka data pada address1
tidak akan berubah, jika kita ingin merubah address1
atau semua variable yang mengacu ke Address
maka kita harus menggunakan operator *
.

Jika kita menggunakan kode di atas yang tidak mengugnakan operator *
maka hasil nya adalah di memory akan membuat data baru dan tidak merubah data yang lama. Nah jika kita menggunakan operator *
maka hasilnya akan seperti berikut

Jadi dengan menggunakan operator *
kita dapat memaksa semua yang me refer ke Address1
untuk pindah ke Address2
. Nah caranya kita hanya perlu menambahkan operator *
di depan nama variable seperti berikut
package main
import "fmt"
type Address struct {
City, Provience, Country string
}
func main() {
var address1 Address = Address{"Subang", "Jawa Barat", "Indonesia"}
var address2 *Address = &address1
address2.City = "Bandung"
*address2 = Address{"Malang", "Jawa Timur", "Indonesia"}
fmt.Println(address1)
fmt.Println(address2)
}

Dengan operator *
seperti kode diatas, kita memaksa semua yang sebelumnya merefer ke memory Address1
menjadi ke Address2
.
Sebagai pembuktian coba buat address3
yang me refer ke address1
seperti berikut
package main
import "fmt"
type Address struct {
City, Provience, Country string
}
func main() {
var address1 Address = Address{"Subang", "Jawa Barat", "Indonesia"}
var address2 *Address = &address1
var address3 *Address = &address1
address2.City = "Bandung"
*address2 = Address{"Malang", "Jawa Timur", "Indonesia"}
fmt.Println(address1)
fmt.Println(address2)
fmt.Println(address3)
}

Pada kode diatas kita membuat address3
baru yang me refer ke address1
dengan begini kita sudah memiliki 3 variable yang merefer ke Address
dan pada baris ke 16 kita merubah semua data address2
dengan operator *
. Coba jalankan kode diatas

Bisa dilihat pada output di atas jika semua variable yang me refer ke Address1
akan berubah dan berpindah menjadi data Address2
.
Function new
Sebelumnya kita membuat pointer dengan operator &
, lebih tepatnya operator ini digunakan untuk membuat pointer dari variable yang sudah ada. Nah bagaimana jika kita ingin membuat pointer dari data yang isinya kosong kita bisa menggunakan function new
. Namun bedanya function new
hanya mengembalikan pointer ke data kosong, artinya tidak ada data awal.
package main
import "fmt"
type Address struct {
City, Provience, Country string
}
func main() {
alamat1 := new(Address)
alamat2 := alamat1
alamat2.City = "Bandung"
fmt.Println(alamat1)
fmt.Println(alamat2)
}

Pada baris ke 10 kita membuat pointer ke data Address
dengan nama variable alamat1
dan di baris 11 kita me refer alamat2
ke alamat1
, oleh karena itu jika kita merubah filed City
di alamat2
maka pada alamat1
juga akan ikut berubah.

Penutup
Pada artikel kali ini kita telah belajar apa itu pointer dan cara menggunakannya pada bahasa pemrogaman golang. Dan pada artikel selanjutnya saya akan membahas Pointer di function pada golang.