Conceptos básicos de funciones y métodos
10 ejemplos para empezar con Funciones e Interfaces: 7 básicos y 3 intermedios.
Busca en todas las páginas de la documentación
10 ejemplos para empezar con Funciones e Interfaces: 7 básicos y 3 intermedios.
go version).Las funciones de Go devuelven valores explícitos, a menudo un resultado más un error.
package main
import (
"fmt"
"strconv"
)
func parsePort(s string) (int, error) {
return strconv.Atoi(s)
}
func main() {
port, err := parsePort("8080")
if err != nil {
fmt.Println("parse:", err)
return
}
fmt.Println("listening on", port)
}error en el punto de llamada: el flujo de control permanece visible._.Relacionado: Retornos Múltiples, Retornos Nombrados y Retornos Desnudos - cuándo nombrar resultados
Los métodos adjuntan comportamiento a los tipos; los receptores de valor operan sobre una copia.
package main
import "fmt"
type Counter struct {
n int
}
func (c Counter) Value() int {
return c.n
}
func main() {
c := Counter{n: 3}
fmt.Println(c.Value())
}(c Counter) copia la estructura para el cuerpo del método.Relacionado: Métodos: Receptores de Valor vs. Puntero - elección del tipo de receptor
Los receptores de puntero mutan el valor original y manejan estructuras más grandes de manera eficiente.
package main
import "fmt"
type Counter struct {
n int
}
func (c *Counter) Inc() {
c.n++
}
func main() {
c := &Counter{}
c.Inc()
c.Inc()
fmt.Println(c.n)
}(c *Counter) permite que Inc modifique el estado del llamador.c.Inc() en una variable de valor.Las interfaces se satisfacen implícitamente cuando los métodos coinciden.
package main
import "fmt"
type Stringer interface {
String() string
}
type User struct {
Name string
}
func (u User) String() string {
return "user:" + u.Name
}
func printLabel(s Stringer) {
fmt.Println(s.String())
}
func main() {
printLabel(User{Name: "ada"})
}User nunca menciona Stringer: el compilador lo verifica en la asignación.Relacionado: Definición e Implementación de Interfaces - patrones de diseño de API
Las funciones son valores de primera clase con sus propios tipos nombrados.
package main
import "fmt"
type Op func(int, int) int
func apply(a, b int, op Op) int {
return op(a, b)
}
func main() {
add := func(x, y int) int { return x + y }
fmt.Println(apply(2, 3, add))
}type Op func(...) documenta la intención mejor que repetir func(int,int) int.Relacionado: Funciones Variádicas y Tipos de Función - patrones variádicos y HOF
El último parámetro puede absorber una lista de argumentos variable.
package main
import "fmt"
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
func main() {
fmt.Println(sum(1, 2, 3, 4))
}nums ...int es un slice dentro de la función ([]int).sum(vals...).Los nombres de resultado actúan como variables en el cuerpo de la función y aparecen en la documentación.
package main
import "fmt"
func divide(a, b float64) (quot float64, ok bool) {
if b == 0 {
return 0, false
}
quot = a / b
ok = true
return
}
func main() {
q, ok := divide(10, 2)
fmt.Println(q, ok)
}return desnudo devuelve los valores nombrados actuales; úsalo con moderación para mayor claridad.defer; perjudicial cuando oscurecen la lógica.Relacionado: Retornos Múltiples, Retornos Nombrados y Retornos Desnudos - compensaciones de los retornos desnudos
Las clausuras capturan variables por referencia; los iteradores de bucle necesitan una copia local por iteración.
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
i := i
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println(i)
}()
}
wg.Wait()
}i := i, las gorutinas pueden observar el valor final del bucle.defer wg.Done() se empareja con Add para un cierre limpio del trabajo concurrente.Relacionado: Literales de Función y Clausuras - patrones de fábrica y middleware
Conecta las dependencias a través de interfaces pequeñas; los constructores devuelven tipos concretos.
package main
import (
"context"
"fmt"
)
type Notifier interface {
Notify(ctx context.Context, msg string) error
}
type Logger struct{}
func (Logger) Notify(ctx context.Context, msg string) error {
fmt.Println("notify:", msg)
return nil
}
type Service struct {
n Notifier
}
func NewService(n Notifier) *Service {
return &Service{n: n}
}
func (s *Service) Run(ctx context.Context) error {
return s.n.Notify(ctx, "ready")
}
func main() {
svc := NewService(Logger{})
_ = svc.Run(context.Background())
}NewService acepta Notifier para pruebas; devuelve *Service como API concreta.context.Context como primer parámetro en los límites de E/S.Relacionado: Funciones e Interfaces: El Modelo de Composición de Go - modelo mental para la composición
Un puntero nil almacenado en una interfaz no es igual a una interfaz nil sin tipo.
package main
import "fmt"
type Worker interface {
Work() error
}
type job struct{}
func (j *job) Work() error { return nil }
func main() {
var w Worker = (*job)(nil)
fmt.Println(w == nil)
}w contiene el tipo *job con valor nil; la interfaz en sí misma no es nil.if w == nil falla a pesar de que no existe una instancia concreta.Relacionado: Interfaz Nil vs. Puntero Nil - diseños de API que evitan la trampa
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado GC de Green Tea, modernizadores de go fix - verificar parche en la compilación), chi (última versión - verificar en la compilación), gin (última versión - verificar en la compilación), echo (última versión - verificar en la compilación), google.golang.org/grpc (última versión - verificar en la compilación), sigs.k8s.io/controller-runtime (última versión - verificar en la compilación), kubebuilder (última versión - verificar en la compilación), tinygo (última versión - verificar objetivos de placa en la compilación), wazero (última versión - verificar en la compilación) y golangci-lint (última versión - verificar conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 18 jul 2026