0Pricing
Go Academy · Lección

Punteros y funciones

Paso por valor frente a paso mediante puntero

Punteros y funciones es una lección gratuita de Go Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Go Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Go Academy incluye 4 lecciones en total.

Paso por valor

Go pasa todos los argumentos de las funciones por valor, es decir, crea una copia. Los cambios realizados dentro de la función no afectan al original:

package main
import "fmt"

func increment(n int) { n++ }

func main() {
    x := 5
    increment(x)
    fmt.Println(x) // 5 — unchanged
}

Pasar mediante un puntero

Pase un puntero para permitir que la función modifique el original:

package main
import "fmt"

func increment(n *int) { *n++ }

func main() {
    x := 5
    increment(&x)
    fmt.Println(x) // 6
}

Devolver punteros

Las funciones pueden devolver punteros a valores asignados en el heap. El análisis de escape de Go garantiza la seguridad:

package main
import "fmt"

func newInt(v int) *int { return &v }

func main() {
    p := newInt(42)
    fmt.Println(*p) // 42
}

Eficiencia con estructuras grandes

Pasar una estructura grande mediante un puntero evita una copia costosa:

package main
import "fmt"

type BigData struct{ Data [1024]int }

func process(d *BigData) { d.Data[0] = 99 }

func main() {
    bd := BigData{}
    process(&bd)
    fmt.Println(bd.Data[0]) // 99
}

Puntero a una interfaz

Rara vez es necesario: las interfaces ya contienen internamente un puntero. Pasar *interface{} casi siempre es incorrecto:

package main
import "fmt"

type Stringer interface{ String() string }

func print(s Stringer) { fmt.Println(s.String()) }

// Pass interface directly, NOT *Stringer
type Name string
func (n Name) String() string { return string(n) }

func main() {
    print(Name("Alice"))
}

Parámetros opcionales con punteros

Utilice parámetros de tipo puntero para distinguir entre «no proporcionado» y el valor cero:

package main
import "fmt"

func greet(name *string) {
    if name == nil {
        fmt.Println("Hello, stranger")
        return
    }
    fmt.Println("Hello,", *name)
}

func main() {
    s := "Alice"
    greet(&s)
    greet(nil)
}

Modificación mediante slices

Los slices ya contienen un puntero interno, por lo que a menudo no necesita *[]T. Sin embargo, cuando append reasigna memoria, necesita un puntero al propio slice:

package main
import "fmt"

func addItem(s *[]int, v int) { *s = append(*s, v) }

func main() {
    nums := []int{1, 2, 3}
    addItem(&nums, 4)
    fmt.Println(nums) // [1 2 3 4]
}

Alias de punteros

Varios punteros a la misma variable crean aliasing: un cambio realizado mediante un puntero es visible a través de todos los demás:

package main
import "fmt"

func main() {
    x := 10
    a, b := &x, &x
    *a = 99
    fmt.Println(*b) // 99 — same memory
}

Evitar el uso excesivo de punteros

Utilice punteros solo cuando sea necesario:

  • Para modificar datos dentro de una función
  • Para estructuras grandes (>= ~64 bytes)
  • Para usar nil con el significado de «ausente»

El uso excesivo de punteros aumenta la presión sobre el recolector de basura y reduce la claridad del código.

Patrón de punteros a funciones

Almacene punteros a funciones en un mapa para crear tablas de despacho:

package main
import "fmt"

func add(a, b int) int { return a + b }
func sub(a, b int) int { return a - b }

func main() {
    ops := map[string]func(int,int)int{
        "+": add, "-": sub,
    }
    fmt.Println(ops["+"](10, 3)) // 13
    fmt.Println(ops["-"](10, 3)) // 7
}

Comprobación rápida

¿Cómo permite que una función modifique una variable entera definida por el código que la llama?

Repaso

Conclusiones principales:

  • Go utiliza paso por valor; use punteros para modificar datos
  • Devuelva punteros desde los constructores para asignar memoria en el heap
  • Los slices contienen un puntero interno, pero append puede requerir *[]T
  • Evite usar punteros en exceso; prefiera valores para los tipos pequeños

Propuesta de práctica

Escriba una función normalize que reciba *[]string y convierta todas las cadenas a minúsculas directamente en el slice mediante strings.ToLower.

Preguntas frecuentes

¿La lección «Punteros y funciones» es gratis?

Sí — el texto completo de «Punteros y funciones» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Go Academy, actualiza a CoddyKit PRO. El curso de Go Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Punteros y funciones»?

Paso por valor frente a paso mediante puntero Practicas Go Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Go Academy?

No se requiere experiencia previa. Go Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «Punteros y funciones»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Go Academy?

Sí. Cada lección de Go Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. ¿Qué son los punteros?
  2. Punteros y funciones
  3. Receivers por puntero en métodos
  4. new() y cuándo usar punteros
← Volver a Go Academy