Introducción
En la sección anterior, completaste un programa básico de Go, que incluyó las siguientes líneas de código:
package main
import "fmt"
¿Cómo entendemos estas dos líneas de código? ¿Cómo usamos efectivamente las declaraciones package e import?
En este laboratorio (lab), aprenderás cómo crear e importar paquetes en Go. Esto te permitirá organizar tu código en módulos reutilizables, lo que hará que tus proyectos de Go sean más mantenibles y escalables.
Puntos de conocimiento:
- Definición y declaración de un paquete
- Comprensión de los identificadores exportados (públicos) y no exportados (privados)
- Diferentes formas de importar paquetes: importación individual, agrupada, con punto, con alias y anónima
Declaración y definición de paquetes
Un paquete en Go es similar a los módulos en Python o las bibliotecas en C. Es una colección de archivos de código fuente utilizados para organizar y reutilizar código. Cada archivo de Go debe declarar un paquete al principio del archivo.
Nota: Un programa de Go debe tener uno y solo un paquete llamado
main, que sirve como punto de entrada para la ejecución. Sin él, el programa no puede generar un archivo ejecutable.
Puntos clave:
- Identificadores exportados (públicos): Los identificadores (variables, funciones, tipos, etc.) que comienzan con una letra mayúscula son accesibles desde otros paquetes. Puedes pensar en ellos como la interfaz pública de tu paquete.
- Identificadores no exportados (privados): Los identificadores que comienzan con una letra minúscula son solo accesibles dentro del mismo paquete. Estos se consideran detalles de implementación internos del paquete.
- Cohesión del paquete: Todos los archivos en la misma carpeta deben pertenecer al mismo paquete. Esto asegura que el código relacionado se mantenga juntos.
- Convenciones de nomenclatura de paquetes: Los nombres de los paquetes deben ser en minúsculas, cortos y descriptivos, evitando guiones bajos o letras mayúsculas.
Vamos a crear nuestro propio paquete personalizado:
Crea una carpeta llamada
propagandisty un archivopropagandist.godentro de ella:mkdir ~/project/propagandist touch ~/project/propagandist/propagandist.goEscribe el siguiente código en
propagandist.go:package propagandist var Shout = "I Love LabEx" // Public variable var secret = "I love the dress" // Private variable func Hit() string { return "Don't hit me, please!" }Shoutes público porque comienza con una letra mayúscula. Esto significa que puedes acceder a él desde otros paquetes que importenpropagandist.secretes privado porque comienza con una letra minúscula. Solo se puede usar dentro del paquetepropagandist.Hites una función pública, accesible desde otros paquetes.
Inicializa un módulo de Go para el paquete:
cd ~/project/propagandist go mod init propagandistEste comando inicializa un nuevo módulo de Go en el directorio
propagandist, lo que ayuda a gestionar las dependencias del paquete.
Importación de un solo elemento
Para usar el paquete propagandist, vamos a crear un nuevo programa de Go. Este paso demostrará cómo importar y usar un solo paquete en tu código de Go.
Crea un nuevo archivo de Go llamado
pacExercise.goen la carpeta del proyecto:touch ~/project/pacExercise.goInicializa un módulo de Go para el programa:
cd ~/project go mod init pacExerciseActualiza el archivo
go.modpara incluir la dependencia del paquete local. Ejecuta el siguiente comando en la terminal:echo "replace propagandist =>./propagandist" >> go.modImportante: Este comando agrega una directiva
replacea tu archivogo.mod. Esto es crucial porque le dice a Go que el paquetepropagandistdebe obtenerse del directorio local./propagandisten lugar de intentar descargarlo de un repositorio remoto. Debes ejecutar este comando en tu terminal, lo que agregará la líneareplace propagandist =>./propagandista tu archivogo.mod. No escribas directamente esta línea en el archivo manualmente.Escribe el siguiente código en
pacExercise.gopara importar y usar el paquetepropagandist:package main import ( "fmt" "propagandist" ) func main() { fmt.Println(propagandist.Shout) // Access the public variable }- Este código importa el paquete
fmtpara imprimir salida y el paquetepropagandist. - Luego accede a la variable pública
Shoutdel paquetepropagandistutilizandopropagandist.Shout.
- Este código importa el paquete
Ejecuta el programa:
go mod tidy go run pacExercise.goEl comando
go mod tidyasegura que tu archivogo.modse actualice con cualquier nueva dependencia. El comandogo run pacExercise.gocompila y ejecuta el programa.Salida esperada:
I Love LabEx
Importaciones agrupadas
Cuando se importan múltiples paquetes, se pueden utilizar importaciones agrupadas para mejorar la legibilidad y la organización. Esta es una elección estilística y no cambia la funcionalidad de tu código.
Modifica
pacExercise.gopara utilizar importaciones agrupadas:package main import ( "fmt" "propagandist" ) func main() { fmt.Println(propagandist.Shout) }En el fragmento de código anterior, los paquetes
fmtypropagandistse importan dentro de un solo bloqueimportencerrado entre paréntesis. Esto facilita la lectura y el manejo de múltiples importaciones de paquetes. Esto es exactamente lo mismo que el ejemplo anterior y muestra cómo utilizar la sintaxis de importación agrupada.Ejecuta el programa para confirmar que sigue funcionando:
go run pacExercise.goEl programa debe ejecutarse sin errores y mostrar la misma salida que antes.
Importación con punto
Al utilizar una importación con punto, puedes omitir el prefijo del nombre del paquete al llamar a sus funciones o variables. Esto generalmente se desaconseja a favor de nombres de paquetes explícitos, ya que puede provocar conflictos de espacio de nombres y reducir la legibilidad. Sin embargo, es bueno saber qué es.
Modifica
pacExercise.gopara utilizar una importación con punto parafmt:package main import. "fmt" import "propagandist" func main() { Println(propagandist.Shout) // No `fmt.` prefix needed }
- Aquí,
import. "fmt"significa que puedes usar funciones y variables del paquetefmtdirectamente sin el prefijofmt.. - Por ejemplo, se utiliza
Printlnen lugar defmt.Println.
Ejecuta el programa:
go run pacExercise.goSalida esperada:
I Love LabEx
Importación con alias
Puedes dar un alias a un paquete importado para mayor claridad o para evitar conflictos cuando dos paquetes tienen nombres similares. Esto es útil para hacer que tu código sea más legible y manejar colisiones de espacios de nombres.
Modifica
pacExercise.gopara dar el aliasioal paquetefmt:package main import io "fmt" import "propagandist" func main() { io.Println(propagandist.Shout) // Use the alias `io` instead of `fmt` }import io "fmt"crea un aliasiopara el paquetefmt.- Ahora, se utiliza
io.Printlnen lugar defmt.Println.
Ejecuta el programa:
go run pacExercise.go
Importación anónima
Las importaciones anónimas se utilizan para importar un paquete por sus efectos secundarios, como ejecutar su función init(), sin necesidad de hacer referencia directa a ninguno de sus identificadores exportados. Esto es útil para paquetes que registran controladores (drivers) o realizan otras tareas de inicialización.
Modifica
pacExercise.gopara incluir una importación anónima del paquetetime:package main import ( "fmt" "propagandist" _ "time" // Anonymous import ) func main() { fmt.Println(propagandist.Shout) }import _ "time"es una importación anónima. El guión bajo_se utiliza como un identificador vacío, lo que le dice al compilador que estás importando el paquete por sus efectos secundarios y no harás referencia directa a nada de él en tu código.- La función
init()del paquetetimese ejecutará cuando se ejecute este programa. El paquetetimeno tiene efectos secundarios particulares visibles aquí; sin embargo, muchos paquetes utilizan esto para registrar controladores de base de datos o configuraciones.
Ejecuta el programa:
go run pacExercise.goSalida esperada:
I Love LabEx
Resumen
En este laboratorio, has aprendido:
- Cómo crear y definir paquetes personalizados en Go, encapsulando código reutilizable.
- La diferencia entre identificadores públicos (exportados) y privados (no exportados) y cómo afectan la accesibilidad.
- Varios métodos para importar paquetes, cada uno con su caso de uso:
- Importación de un solo elemento: Importar un paquete a la vez.
- Importación agrupada: Importar múltiples paquetes en un solo bloque para una mejor organización.
- Importación con punto: Importar un paquete y usar sus identificadores directamente sin el prefijo del nombre del paquete. (Usar con precaución)
- Importación con alias: Renombrar paquetes importados para una mejor legibilidad o para evitar conflictos de nombres.
- Importación anónima: Importar un paquete únicamente por sus efectos secundarios, como la inicialización.
- El papel de la función
init()en los paquetes y cómo las importaciones anónimas pueden desencadenar su ejecución.
Al completar este laboratorio, ahora estás capacitado para estructurar y gestionar proyectos de Go utilizando paquetes de manera efectiva. Puedes crear módulos reutilizables, controlar el acceso a los identificadores y organizar mejor tu código, lo que conduce a aplicaciones de Go más mantenibles y escalables.
Summary
In this lab, you learned:
- How to create and define custom packages in Go, encapsulating reusable code.
- The difference between public (exported) and private (unexported) identifiers and how they impact accessibility.
- Various ways to import packages, each with its use case:
- Single-item import: Importing one package at a time.
- Grouped import: Importing multiple packages in a single block for better organization.
- Dot import: Importing a package and using its identifiers directly without the package name prefix. (Use with caution)
- Alias import: Renaming imported packages for better readability or to avoid naming conflicts.
- Anonymous import: Importing a package solely for its side effects, such as initialization.
- The role of the
init()function in packages and how anonymous imports can trigger its execution. - The detailed workings of Go's initialization process, including:
- How package-level variables are initialized before
init()functions - The guaranteed execution order of
init()functions across dependent packages - How multiple
init()functions work within a package - The complete initialization flow from dependent packages to the main function
- How package-level variables are initialized before
By completing this lab, you are now equipped to structure and manage Go projects using packages effectively. You can create reusable modules, control access to identifiers, better organize your code, and understand the initialization process, leading to more maintainable and scalable Go applications.



