Skip to content

Pointer Go

Go mempertahankan pointer pada tingkat tertentu menjamin performa sekaligus untuk GC yang lebih baik dan pertimbangan keamanan membatasi penggunaan pointer.

Membuat

Tentang pointer ada dua operator yang umum digunakan yang pertama adalah operator alamat & yang lain adalah operator dereferensi *. Melakukan alamat pada variabel akan mengembalikan pointer tipe yang sesuai misalnya

go
func main() {
   num := 2
   p := &num
   fmt.Println(p)
}

Pointer menyimpan adalah alamat variabel num

0xc00001c088

Operator dereferensi memiliki dua kegunaan yang pertama adalah mengakses elemen yang ditunjuk oleh pointer yaitu dereferensi misalnya

go
func main() {
  num := 2
  p := &num
  rawNum := *p
  fmt.Println(rawNum)
}

p adalah pointer melakukan dereferensi pada tipe pointer dapat mengakses elemen yang ditunjuk oleh pointer. Ada satu kegunaan lagi adalah mendeklarasikan pointer misalnya

go
func main() {
   var numPtr *int
   fmt.Println(numPtr)
}
<nil>

*int yaitu mewakili tipe variabel ini adalah pointer tipe int tetapi pointer tidak bisa hanya mendeklarasikan harus menginisialisasi perlu mengalokasikan memori untuknya jika tidak adalah pointer kosong tidak dapat digunakan secara normal. Baik menggunakan operator alamat memberikan alamat variabel lain ke pointer ini atau menggunakan fungsi built-in new untuk mengalokasikan secara manual misalnya

go
func main() {
   var numPtr *int
   numPtr = new(int)
   fmt.Println(numPtr)
}

Lebih banyak menggunakan variabel pendek

go
func main() {
   numPtr := new(int)
   fmt.Println(numPtr)
}

Fungsi new hanya memiliki satu parameter yaitu tipe dan mengembalikan pointer tipe yang sesuai fungsi akan mengalokasikan memori untuk pointer ini dan pointer menunjuk ke nilai nol dari tipe yang sesuai misalnya

go
func main() {
   fmt.Println(*new(string))
   fmt.Println(*new(int))
   fmt.Println(*new([5]int))
   fmt.Println(*new([]float64))
}

0
[0 0 0 0 0]
[]

Larangan Operasi Pointer

Di Go tidak mendukung operasi pointer yaitu pointer tidak dapat offset mari lihat kode C++ terlebih dahulu

cpp
int main() {
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int *p = &arr[0];
    cout << &arr << endl
         << p << endl
         << p + 1 << endl
         << &arr[1] << endl;
}
0x31d99ff880
0x31d99ff880
0x31d99ff884
0x31d99ff884

Dapat dilihat alamat array dengan alamat elemen pertama angka sama dan setelah operasi tambah satu pada pointer elemen yang ditunjuk adalah elemen kedua array. Di Go array juga sama tetapi perbedaannya adalah pointer tidak dapat offset misalnya

go
func main() {
   arr := [5]int{0, 1, 2, 3, 4}
   p := &arr
   println(&arr[0])
   println(p)
   // Mencoba melakukan operasi pointer
   p++
   fmt.Println(p)
}

Program seperti ini tidak akan bisa dikompilasi error adalah sebagai berikut

main.go:10:2: invalid operation: p++ (non-numeric type *[5]int)

TIP

Pustaka standar unsafe menyediakan banyak operasi untuk pemrograman tingkat rendah di antaranya termasuk operasi pointer pergi ke pustaka standar-unsafe untuk memahami detail.

new dan make

Di beberapa bagian sebelumnya sudah banyak kali disebutkan fungsi built-in new dan make keduanya agak mirip tetapi juga berbeda mari review kembali.

go
func new(Type) *Type
  • Nilai pengembalian adalah pointer tipe
  • Parameter yang diterima adalah tipe
  • Khusus digunakan untuk mengalokasikan ruang memori untuk pointer
go
func make(t Type, size ...IntegerType) Type
  • Nilai pengembalian adalah nilai bukan pointer
  • Parameter pertama yang diterima adalah tipe parameter variadic sesuai dengan tipe yang diteruskan berbeda
  • Khusus digunakan untuk mengalokasikan memori untuk slice map channel.

Berikut adalah beberapa contoh

go
new(int) // pointer int
new(string) // pointer string
new([]int) // pointer slice integer
make([]int, 10, 100) // slice integer dengan panjang 10 kapasitas 100
make(map[string]int, 10) // map dengan kapasitas 10
make(chan int, 10) // channel dengan ukuran buffer 10

Golang by www.golangdev.cn edit