Los punteros son accesos a la memoria, es decir, cuando guardamos una variable, lo que hace el runtime es crear una dirección de memoria y a esa dirección le guarda el valor de esa variable.

Para obtener la dirección en memoria de una variable, observemos el siguiente código:

package main

import "fmt"

func main(){

	a := 50
	b := &a 
	
	fmt.Println(a)
	fmt.Println(b)

}

Respuesta:

50
0xc0000140d0

Para acceder al valor de la dirección en memoria se hace del siguiente modo:

package main

import "fmt"

func main(){

	a := 50
	b := &a 
	
	fmt.Println(b)
	fmt.Println(*b)

}

Respuesta:

0xc0000140d0
50

<aside> 💡 El & es para acceder a la dirección en memoria de una variable.

</aside>

<aside> 💡 El * es para acceder al valor de esa dirección en memoria.

</aside>


Si modificamos el valor que está apuntando a esa dirección en memoria, las demás variables que apunten a esa dirección en memoria van a cambiar su valor.

package main

import "fmt"

func main(){

	a := 50
	b := &a 

	*b = 100
	fmt.Println(a)

}
100

Los punteros son útiles para modificar atributos de un struct de una manera más optima:

package main

import "fmt"

type pc struct {
	ram int
	disk int
	brand string
}

func (myPc *pc) duplicateRam(){ //Es la forma como aplicamos funciones a los structs

	myPc.ram = myPc.ram * 2

}

func main(){

	myPc := pc{ram: 16, disk: 200, brand: "msi"}
	fmt.Println(myPc)

	myPc.duplicateRam()
	fmt.Println(myPc)

	myPc.duplicateRam()
	fmt.Println(myPc)

}