🎱Punteros * &
¿Qué es un puntero en Go?
Un puntero es una variable que almacena la dirección de memoria de otra variable. En Go, los punteros son útiles para trabajar directamente con la memoria y modificar el valor original de una variable.
Cómo declarar y usar punteros:
Para declarar un puntero, se utiliza el símbolo `` antes del tipo de dato.
El operador
&
se usa para obtener la dirección de memoria de una variable.El operador `` se usa para acceder (o desreferenciar) el valor almacenado en la dirección de memoria a la que apunta el puntero.
Ejemplo
package main
import "fmt"
func main() {
var a int = 10 // Variable normal
var p *int = &a // Puntero a 'a'
fmt.Println(a) // 10
fmt.Println(p) // Dirección de memoria de 'a'
fmt.Println(*p) // 10 (valor al que apunta el puntero) DESREFERENCIACION
}
Paso de parámetros por valor y por puntero:
En Go, las funciones pasan argumentos por valor, lo que significa que se crea una copia del valor. Si quieres modificar la variable original dentro de una función, debemos pasar su puntero.
Ejemplo con paso por valor:
En este caso, pasamos una copia del valor a la función. La variable original no se ve afectada.
package main
import "fmt"
// Función que recibe un valor por valor
func incrementarPorValor(x int) {
x = x + 1
fmt.Println("Dentro de la función incrementarPorValor:", x) // 11
}
func main() {
a := 10
incrementarPorValor(a)
fmt.Println("Después de la función incrementarPorValor:", a) // 10
}
Explicación:
En
incrementarPorValor
, el valor dea
(que es 10) se copia y luego se incrementa a 11 dentro de la función.Sin embargo, al finalizar la función, la variable original
a
no cambia, porque solo se trabajó con una copia del valor.
Ejemplo con paso por puntero:
Aquí pasamos la dirección de memoria de la variable original, por lo que los cambios se reflejan en la variable original, porque con puntero accedemos al valor original, este sirve para cuando queramos manejar muchos datos y no queramos gastar uso de memoria en uso de copias sino acceder al valor original.
package main
import "fmt"
// Función que recibe un valor por puntero
func incrementarPorPuntero(x *int) {
*x = *x + 1
fmt.Println("Dentro de la función incrementarPorPuntero:", *x) // 11
}
func main() {
a := 10
incrementarPorPuntero(&a)
fmt.Println("Después de la función incrementarPorPuntero:", a) // 11
}
Explicación:
En
incrementarPorPuntero
, pasamos la dirección de memoria dea
usando&a
. Esto permite que la función modifique el valor original dea
.Después de la función, el valor de
a
es 11 porque trabajamos directamente sobre su dirección de memoria.
Diferencia clave:
Por
valor
: La función trabaja con una copia del valor, no afecta a la variable original.Por
puntero
: La función trabaja directamente sobre la variable original, y cualquier modificación es persistente.Me piden crear una función que ****reciba una estructura por puntero y modifique uno de sus campos.
Codigo:
type Persona struct { edad int nombre string } // creo un metodo por puntero a la estructura Persona. func (p *Persona) cumplirAños() { p.edad++ //modifico el campo edad fmt.Println("Edad con cumple", p.edad) }
Preguntas:
¿Cuál es la diferencia entre pasar una variable por valor y pasarla por puntero en Go?
¿Qué hace el operador
*
en Go cuando se usa con punteros?¿Cuándo es recomendable pasar una estructura por puntero en vez de por valor en una función?
Escribe una función que reciba una estructura por puntero y modifique uno de sus campos.
// RESPUESTAS:
1. la diferencia radica en que por valor se accedera a una copia del valor original de la variable mientras que por puntero accederiamos al valor original sin crear una copia.
2. es el operador que define un puntero, pero tambien se usa para desreferenciar un puntero con el fin de poder acceder al valor original.
3. cuando la estructura maneja demasiados datos en este caso no es recomendable por valor ya que a nivel de optimizacion se haria doble trabajo al crear copias de toda la estructura mientras que con puntero accederiamos al valor original asi que eso es.
4.
type Persona struct {
edad int
nombre string
}
// creo un metodo por puntero a la estructura Persona.
func (p *Persona) cumplirAños() {
p.edad++ //modifico el campo edad
fmt.Println("Edad con cumple", p.edad)
}
Last updated