Değişkenler, değer içeren depolama parçalarıdır. Biz yaptığımız tanımlamalarda, değişkenlerin değerlerini okur veya onlara yeni değerler atarız.
Pointer‘lar ise değişkenlerin adresleridir. Yani Pointer değerin saklandığı konumdur. Her değerin bir adresi yoktur ama her değişkenin mutalaka bir adresi vardır. Pointer ile bir değişkenin adını kullanmadan hatta adını bilmeden, dolaylı olarak o değişkenin değerini okuyabilir veya güncelleyebiliriz. Golang içerisinde Pointer denildiğin * ve & operatörlerini bilmemiz gerekir. & operatörü değişkenin adresini bulmakta kullanılırken, * operatörü ise Pointer’ın işaret ettiği adresteki değer alınır. Şimdi bu söylediklerimizi bir örnekle pekiştirelim.
package main
import "fmt"
func main() {
kby := 58 //kby değişkenine 58 değerini atadık.
emy := &kby //emy bir pointer oldu. İçerisinde kby değişkeninin tutulduğu bellek adresi var.
fmt.Println("kby=", kby) //kby değeri
fmt.Println("emy pointer address=", emy) //bellek adresi
fmt.Println("emy pointer value=", *emy) //bellek adresindeki değer
}

Şimdi daha önce söylediğimiz gibi adını bile bilmediğimiz bir değişkenin değerini değiştirelim
package main
import "fmt"
func main() {
//Önce kby isimli bir değişken tanımlauyacağız.
//Ardından kby değişkenini pointer olarak emy atayacağız.
//emy pointerını da kay isimli başka bir pointera atayacağız.
//kay pointerının değerine 34 atayacağız.
//En son tümünün değerlerine bakacağız.
kby := 58 //kby değişkenine 58 değerini atadık.
emy := &kby //emy bir pointer oldu. İçerisinde kby değişkeninin tutulduğu bellek adresi var.
kay := emy
*kay = 34
fmt.Println("kby=", kby) //kby değeri
fmt.Println("emy pointer address=", emy) //bellek adresi
fmt.Println("kay pointer address=", kay) //bellek adresindeki değer
fmt.Println("kby=", kby) //kby değeri
fmt.Println("emy value=", *emy) //bellek adresi
fmt.Println("kay value=", *kay) //bellek adresindeki değer
}

Fonksiyonlarda Pointer Kullanımı
Pointer bir değişkenin adresini içerdiğinden, bir fonksiyona Pointer bağımsız değişkeni iletilmesi, fonksiyonun dolaylı olarak gönderilen değişkeni güncelleştirmesini mümkün kılar. Sanırım örnekle daha iyi anlayacağız.
package main
import "fmt"
func main() {
//İlk fonksiyonda parametre olarak pointer göndermedik.
//Main fonksiyonu içerisindeki kby değişkenini etkilenmediğini gördük.
//İkinci fonksiyonda ise pointer olarak gönderdik.
//Kby değişkeninin değiştiğini siz de farketmiştirsiniz.
//Alttaki çıktılara baktığımızda fonksiyon içerisindeki p değişkeni ile
//Main fonksyionu içerisindeki kby değişkeninin hem değeri hem adresi aynıdır.
kby := 58 //kby değişkenine 58 değerini atadık.
incr(kby)
fmt.Println("kby=", kby) //kby değeri
fmt.Println("kby pointer address=", &kby)
fmt.Println("***********")
incrWithPointer(&kby)
fmt.Println("kby=", kby) //kby değeri
fmt.Println("kby pointer address=", &kby)
}
func incr(p int) {
p += 1
fmt.Println("p value=", p) //p değeri
fmt.Println("p pointer address=", &p) //p bellek adresi
}
func incrWithPointer(p* int) {
*p += 1
fmt.Println("p value=", *p) //p değeri
fmt.Println("p pointer address=", p) //p bellek adresi
}