Fundamentos de Tipos de Datos
10 ejemplos para empezar con el sistema de tipos y el comportamiento de la memoria de Go - 7 básicos y 3 intermedios.
Busca en todas las páginas de la documentación
10 ejemplos para empezar con el sistema de tipos y el comportamiento de la memoria de Go - 7 básicos y 3 intermedios.
Instale Go 1.26.x y ejecute los ejemplos desde cualquier directorio de módulo:
go version # se espera go1.26.x
mkdir -p /tmp/go-types-demo && cd /tmp/go-types-demo
go mod init example.com/types-demoGuarde cada fragmento como main.go (o combine en un solo main con funciones separadas) y ejecute go run ..
Cada variable declarada sin un inicializador recibe el valor cero de su tipo.
package main
import "fmt"
func main() {
var i int
var s string
var p *int
fmt.Printf("int=%d string=%q ptr=%v\n", i, s, p)
}0, "", false, nil son los valores cero comunes para tipos numéricos, de cadena, booleanos y similares a referencias.nil).var cuando el valor cero sea significativo; use := con un literal cuando no lo sea.Relacionado: Modelo de Memoria de Go - por qué la semántica de valor comienza en los valores cero.
Los arrays tienen un tamaño fijo en el tipo; los slices son vistas dinámicas sobre un array subyacente.
package main
import "fmt"
func main() {
var arr [3]int = [3]int{1, 2, 3}
sl := []int{10, 20, 30}
fmt.Println(len(arr), len(sl), cap(sl))
}[3]int y [4]int son tipos diferentes - los arrays rara vez son parámetros de función en las APIs.len es la longitud; cap es la capacidad desde el primer elemento del slice hasta el final del array subyacente.Relacionado: Internos de Slice - puntero, len, cap y layout de append.
Los mapas asocian claves con valores. Un mapa nil es legible pero no escribible.
package main
import "fmt"
func main() {
var m map[string]int
fmt.Println(m["missing"]) // 0, no hay panic
m = make(map[string]int)
m["go"] = 1
fmt.Println(m["go"])
}make o un literal antes de insertar.sync.Map.Relacionado: Internos de Mapas - crecimiento y orden de iteración.
Los structs agrupan campos con semántica de valor a menos que almacene punteros.
package main
import (
"encoding/json"
"fmt"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
func main() {
u := User{ID: 1, Name: "Ada"}
b, _ := json.Marshal(u)
fmt.Println(string(b))
}encoding/json solo ve campos exportados.reflect en tiempo de ejecución.Relacionado: Alineación de Structs - padding y
unsafe.Sizeof.
& toma una dirección; * desreferencia. Go no tiene aritmética de punteros en código seguro.
package main
import "fmt"
func bump(n *int) {
*n++
}
func main() {
x := 10
bump(&x)
fmt.Println(x)
}new(T) devuelve *T inicializado a cero - equivalente a var v T; return &v cuando escapa.Relacionado: Punteros
unsafe- cuándounsafe.Pointerestá justificado.
interface{} (o any) contiene cualquier valor; otras interfaces contienen valores con métodos específicos.
package main
import "fmt"
type Greeter interface {
Greet() string
}
type Person struct{ Name string }
func (p Person) Greet() string { return "hello, " + p.Name }
func describe(v any) {
fmt.Printf("%T %v\n", v, v)
}
func main() {
var g Greeter = Person{Name: "Ada"}
describe(g)
fmt.Println(g.Greet())
}implements.%T imprime el tipo dinámico - esencial al depurar parámetros any.var i any) difiere de una interfaz que contiene un puntero nil tipado.Relacionado: Internos de Interfaces - itables y tipo dinámico.
Los canales transfieren valores entre goroutines con semántica de bloqueo.
package main
import "fmt"
func main() {
ch := make(chan int, 1)
ch <- 42
v := <-ch
fmt.Println(v)
}make(chan T) no tiene búfer - sincronización de envío y recepción.make(chan T, n) almacena en búfer n envíos sin un receptor coincidente.ok == false.Relacionado: Internos de Canales - reglas de bloqueo en detalle.
Extraiga tipos concretos de interfaces de forma segura.
package main
import "fmt"
func parse(v any) {
switch x := v.(type) {
case int:
fmt.Println("int", x*2)
case string:
fmt.Println("string", len(x))
default:
fmt.Printf("otro %T\n", x)
}
}
func main() {
parse(21)
parse("go")
}x, ok := v.(int) evita el panic en asignaciones fallidas.Relacionado: Interfaz Nil vs Puntero Nil - trampas de asignación con nil tipado.
copyLa creación de sub-slices comparte un array subyacente; copy duplica elementos en un slice existente.
package main
import "fmt"
func main() {
src := []int{1, 2, 3, 4}
dst := make([]int, 2)
n := copy(dst, src[1:])
fmt.Println(dst, n, src)
}copy devuelve el número de elementos copiados - el mínimo de len(dst) y len(src).dst puede afectar a src si se superponen.append a un nuevo slice con capacidad suficiente cuando necesite una copia independiente.Relacionado: Internos de Slice - cuándo
appendreasigna.
make vs newmake inicializa slices, mapas y canales; new asigna un solo valor y devuelve un puntero.
package main
import "fmt"
func main() {
s := make([]byte, 0, 64)
m := make(map[string]struct{})
c := make(chan struct{})
p := new(int)
fmt.Printf("slice cap=%d map=%v chan=%v *p=%d\n", cap(s), m != nil, c != nil, *p)
}make devuelve un valor inicializado (no nil) listo para usar.new(T) rara vez es necesario - var v T; &v o literales son más claros para structs.make([]T, 0, n) evita el crecimiento repetido de append en bucles intensivos.Relacionado: Tipos de Datos y Mejores Prácticas de Memoria - elección de layouts para el rendimiento.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (GC por defecto Green Tea,
go fixmodernizadores - verificar parche en la compilación), chi (última - verificar en la compilación), gin (última - verificar en la compilación), echo (última - verificar en la compilación), google.golang.org/grpc (última - verificar en la compilación), sigs.k8s.io/controller-runtime (última - verificar en la compilación), kubebuilder (última - verificar en la compilación), tinygo (última - verificar objetivos de placa en la compilación), wazero (última - verificar en la compilación) y golangci-lint (última - verificar conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026