Muchas tareas que antes requerían cgo ahora tienen rutas pure-Go: golang.org/x/sys para llamadas al sistema, puertos de la comunidad de bibliotecas de criptografía y compresión, y paquetes de la biblioteca estándar que envuelven directamente las APIs del SO.
Elegir pure Go primero mantiene la compilación cruzada, los binarios estáticos y la CI más simples.
Lista las entradas del directorio con x/sys en Unix en lugar de libc envuelto por cgo.
package mainimport ( "fmt" "os" "golang.org/x/sys/unix")func main() { dir, err := os.Open(".") if err != nil { panic(err) } defer dir.Close() // Prefiere os.ReadDir en código de aplicación; unix.ReadDirent muestra la forma de x/sys buf := make([]byte, 4096) for { n, err := unix.ReadDirent(int(dir.Fd()), buf) if err != nil || n == 0 { break } // Analiza buf según unix.ParseDirent en helpers de producción fmt.Printf("leídos %d bytes de datos dirent\n", n) }}
Lo que esto demuestra:
Los descriptores de archivo de os.File alimentan las llamadas al sistema unix sin cgo.
golang.org/x/sys rastrea las diferencias de plataforma por GOOS.
El código de aplicación generalmente debería preferir APIs de os de nivel superior; x/sys es para huecos.
Los paquetes de llamadas al sistema pure-Go usan "stubs" de ensamblaje o intrínsecos del compilador generados por plataforma para invocar la interfaz de interrupción del kernel.
No se requiere un compilador C; go build con CGO_ENABLED=0 todavía tiene éxito.
golang.org/x/sys es el hogar mantenido para constantes y funciones de bajo nivel; el paquete syscall de la biblioteca estándar está congelado por compatibilidad.
Los puertos de la comunidad (SQLite pure Go, imágenes, compresión) reimplementan algoritmos en Go o usan //go:embed para tablas de datos en lugar de enlazar C.
Usar el paquete syscall obsoleto para código nuevo - Se pierden correcciones en x/sys. Solución: Importa golang.org/x/sys/unix o windows y migra los sitios de llamada.
Asumir que pure-Go significa más lento - Los puertos modernos a menudo igualan a cgo para trabajo ligado a I/O; la criptografía ligada a CPU puede diferir. Solución: Haz benchmarks en tu carga de trabajo antes de elegir.
Elegir mattn/go-sqlite3 en CI estática - Requiere cgo y cuidado con musl/glibc. Solución: Usa modernc.org/sqlite cuando CGO_ENABLED=0 sea innegociable.
Reimplementar ioctl adivinando los diseños de struct - Se rompe entre versiones del kernel. Solución: Sigue las definiciones de x/sys o la documentación oficial del SO; añade etiquetas de compilación por arquitectura.
Ignorar etiquetas de compilación en características opcionales de cgo - Los consumidores no pueden compilar sin una cadena de herramientas C. Solución: Distribuye implementaciones !cgo o documentación clara del requisito obligatorio de cgo.
RPC para evitar cgo cuando el presupuesto de latencia es de microsegundos - El costo de red empequeñece el dolor de compilación ahorrado. Solución: Mide de extremo a extremo antes de rechazar cgo en proceso.
No, permanece para compatibilidad con la biblioteca estándar, pero está obsoleto para código de aplicación nuevo.
Usa x/sys para nuevas llamadas de bajo nivel.
¿Requiere x/sys cgo?
No, es pure Go con archivos específicos de plataforma y ensamblaje donde sea necesario.
¿Cómo compilo cruzado con pure Go?
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build funciona para paquetes sin import "C".
No se requiere un compilador cruzado C.
¿Cuándo sigue siendo correcto mattn/go-sqlite3?
Cuando necesitas opciones de tiempo de compilación específicas de SQLite o extensiones que solo se exponen a través de la API C.
De lo contrario, evalúa primero los drivers puros.
¿Puedo mezclar x/sys y cgo en un módulo?
Sí, mantén las llamadas al sistema en paquetes pure-Go y aísla cgo en envoltorios.
Evita importar C desde manejadores HTTP activos.
¿Qué pasa con los destinos WASM?
Las llamadas al sistema difieren completamente en js/wasm y wasip1.
Consulta la descripción general de WebAssembly en esta sección; cgo no está disponible allí.
¿Están ioctl y epoll disponibles sin cgo?
golang.org/x/sys/unix expone muchos de ellos en Linux y BSD.
Verifica el soporte para tu combinación GOOS/GOARCH.
¿Cómo encuentro reemplazos pure-Go?
Busca en pkg.go.dev con etiquetas de compilación CGO_ENABLED=0, consulta las listas de Awesome Go y lee los README de los drivers para conocer los requisitos de cgo.
¿Pure Go ayuda a la revisión de seguridad?
Sí, la seguridad de memoria de Go se aplica; menos "blobs" nativos que auditar.
Las bibliotecas C aún necesitan revisión cuando se envuelven.
¿Qué pasa si x/sys no tiene mi syscall?
Contribuye a golang.org/x/sys con constantes generadas a partir de cabeceras oficiales.
Último recurso: un pequeño paquete cgo detrás de una API interna.
¿Puede os/exec reemplazar a cgo para herramientas de línea de comandos?
A menudo sí, llamar externamente a openssl o ffmpeg evita enlazarlos.
Intercambia la sobrecarga del proceso por simplicidad de compilación.
¿Deberían las bibliotecas usar pure Go por defecto?
Los módulos Go idiomáticos envían compilaciones !cgo cuando es factible y documentan aceleradores solo para cgo.
Los consumidores te lo agradecerán en las canalizaciones de CI y compilación cruzada.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado Green Tea GC, go fix modernizers - verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica objetivos de placa en la compilación), wazero (última - verifica en la compilación), y golangci-lint (última - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 18 jul 2026