En el lenguaje Go, la organización del código a través de paquetes (packages) y el sistema de visibilidad juega un papel clave en la modularidad, la reutilización y la encapsulación de la lógica.
A diferencia de muchos lenguajes clásicos con herencia orientada a objetos, Go fue diseñado desde cero en torno a módulos simples: paquetes con reglas claras de exportación e importación. Este legado se relaciona con la filosofía del minimalismo, la simplicidad y el estricto control de dependencias.
Si los componentes no tienen una visibilidad clara, surge un caos en los nombres, es difícil seguir las dependencias entre archivos y aumenta el riesgo de usar accidentalmente detalles privados de la implementación. Los errores en la organización de la exportación pueden llevar a errores difíciles de depurar y a la violación de la encapsulación.
En Go, cada archivo debe pertenecer a algún paquete (package nombre). Toda el área de visibilidad en Go se define:
Todas las funciones, tipos, variables, constantes y métodos cuyo nombre comienza con una letra mayúscula se exportan desde el paquete y están disponibles para otros paquetes tras la importación. Los demás solo están disponibles dentro del paquete.
Ejemplo de estructura:
project/
│
├── main.go // package main
└── mathutil/
└── mathutil.go // package mathutil
Ejemplo de código:
// mathutil/mathutil.go package mathutil // Public - función exportada func Sum(a, b int) int { return a + b } // private - función no exportada func subtract(a, b int) int { return a - b }
// main.go package main import ( "fmt" "project/mathutil" ) func main() { fmt.Println(mathutil.Sum(2, 3)) // 5 // fmt.Println(mathutil.subtract(3,2)) // ¡Error de compilación! subtract no es exportada }
Características clave:
¿Se puede exportar una variable o función declarada con letra minúscula mediante otros mecanismos?
No. En Go no hay palabras clave como public, private, todo se determina solo por la primera letra del nombre (categoría unicode - letra mayúscula).
¿Pueden las funciones de un archivo de paquete utilizar funciones privadas de otro archivo del mismo paquete?
Sí, la visibilidad está limitada a nivel de paquete, no de archivo. Todos los elementos privados son accesibles en todos los archivos de un mismo paquete.
Ejemplo de código:
// mathutil/helpers.go package mathutil func hiddenHelper() int { return 42 } // mathutil/mathutil.go package mathutil func UseHelper() int { return hiddenHelper() // ¡accesible! }
¿Se puede crear la misma función o tipo con el mismo nombre dentro de un paquete en diferentes archivos?
No, habrá un error de compilación: dentro del paquete, los nombres deben ser únicos, incluso si se declaran en diferentes archivos.
xxx_test.go en el mismo paquete)Un gran equipo coloca todas las funciones y tipos auxiliares en el paquete util exportando todo:
Pros:
Contras:
El equipo divide cuidadosamente el código en módulos por áreas de negocio, exportando solo la API:
Pros:
Contras: