Pointers

Pointer adalah variabel yang menyimpan alamat memori dari variabel lain.

Contoh Masalah

Bagaimana cara:

  1. Mengubah nilai variabel dari dalam fungsi
  2. Mengoptimalkan penggunaan memori
  3. Berbagi data antar fungsi

Penyelesaian

package main

import "fmt"

// 1. Fungsi yang mengubah nilai menggunakan pointer
func increment(x *int) {
    *x++ // Mengubah nilai yang ditunjuk pointer
}

// 2. Fungsi yang swap nilai menggunakan pointer
func swap(a, b *int) {
    temp := *a
    *a = *b
    *b = temp
}

// 3. Struct dengan pointer
type Person struct {
    Name string
    Age  int
}

func (p *Person) birthday() {
    p.Age++ // Mengubah nilai age menggunakan pointer receiver
}

// 4. Fungsi yang mengembalikan pointer
func createPerson(name string, age int) *Person {
    return &Person{
        Name: name,
        Age:  age,
    }
}

func main() {
    // Contoh 1: Basic Pointer
    x := 10
    var ptr *int = &x // ptr menyimpan alamat dari x
    
    fmt.Printf("Nilai x: %d\n", x)
    fmt.Printf("Alamat x: %p\n", &x)
    fmt.Printf("Nilai ptr: %p\n", ptr)
    fmt.Printf("Nilai yang ditunjuk ptr: %d\n", *ptr)

    // Contoh 2: Mengubah nilai melalui pointer
    increment(&x)
    fmt.Printf("\nSetelah increment:\n")
    fmt.Printf("Nilai x: %d\n", x)

    // Contoh 3: Swap nilai
    a, b := 5, 10
    fmt.Printf("\nSebelum swap: a = %d, b = %d\n", a, b)
    swap(&a, &b)
    fmt.Printf("Setelah swap: a = %d, b = %d\n", a, b)

    // Contoh 4: Pointer ke struct
    person := &Person{
        Name: "Alice",
        Age:  25,
    }
    
    fmt.Printf("\nSebelum ulang tahun: %+v\n", person)
    person.birthday()
    fmt.Printf("Setelah ulang tahun: %+v\n", person)

    // Contoh 5: Fungsi yang mengembalikan pointer
    newPerson := createPerson("Bob", 30)
    fmt.Printf("\nOrang baru: %+v\n", newPerson)

    // Contoh 6: Pointer ke pointer
    var pp **int = &ptr
    fmt.Printf("\nPointer ke pointer:\n")
    fmt.Printf("Nilai yang ditunjuk pp: %d\n", **pp)

    // Contoh 7: Nil pointer
    var nilPtr *int
    fmt.Printf("\nNil pointer: %v\n", nilPtr)
    
    // Mengecek nil pointer
    if nilPtr == nil {
        fmt.Println("Pointer adalah nil")
    }
}

Penjelasan Kode

  1. Deklarasi Pointer

    • var ptr *Type
    • & untuk mendapatkan alamat
    • * untuk mengakses nilai
  2. Penggunaan Pointer

    • Mengubah nilai variabel
    • Pass by reference
    • Menghemat memori
  3. Pointer ke Struct

    • Method dengan pointer receiver
    • Mengubah field struct
    • Menghindari copy data

Output

Nilai x: 10
Alamat x: 0xc000018098
Nilai ptr: 0xc000018098
Nilai yang ditunjuk ptr: 10

Setelah increment:
Nilai x: 11

Sebelum swap: a = 5, b = 10
Setelah swap: a = 10, b = 5

Sebelum ulang tahun: &{Name:Alice Age:25}
Setelah ulang tahun: &{Name:Alice Age:26}

Orang baru: &{Name:Bob Age:30}

Pointer ke pointer:
Nilai yang ditunjuk pp: 11

Nil pointer: <nil>
Pointer adalah nil

Tips

  • Gunakan pointer untuk mengubah nilai
  • Hindari pointer ke pointer jika bisa
  • Selalu cek nil pointer
  • Pointer receiver untuk method yang mengubah state
  • Pointer berguna untuk struktur data besar