Creación e importación de paquetes de Go

GolangGolangBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

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

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("Golang")) -.-> go/BasicsGroup(["Basics"]) go(("Golang")) -.-> go/FunctionsandControlFlowGroup(["Functions and Control Flow"]) go(("Golang")) -.-> go/AdvancedTopicsGroup(["Advanced Topics"]) go/BasicsGroup -.-> go/variables("Variables") go/FunctionsandControlFlowGroup -.-> go/functions("Functions") go/AdvancedTopicsGroup -.-> go/time("Time") subgraph Lab Skills go/variables -.-> lab-149064{{"Creación e importación de paquetes de Go"}} go/functions -.-> lab-149064{{"Creación e importación de paquetes de Go"}} go/time -.-> lab-149064{{"Creación e importación de paquetes de Go"}} end

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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:

  1. Crea una carpeta llamada propagandist y un archivo propagandist.go dentro de ella:

    mkdir ~/project/propagandist
    touch ~/project/propagandist/propagandist.go
  2. Escribe 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!"
    }
    • Shout es público porque comienza con una letra mayúscula. Esto significa que puedes acceder a él desde otros paquetes que importen propagandist.
    • secret es privado porque comienza con una letra minúscula. Solo se puede usar dentro del paquete propagandist.
    • Hit es una función pública, accesible desde otros paquetes.
  3. Inicializa un módulo de Go para el paquete:

    cd ~/project/propagandist
    go mod init propagandist

    Este 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.

  1. Crea un nuevo archivo de Go llamado pacExercise.go en la carpeta del proyecto:

    touch ~/project/pacExercise.go
  2. Inicializa un módulo de Go para el programa:

    cd ~/project
    go mod init pacExercise
  3. Actualiza el archivo go.mod para incluir la dependencia del paquete local. Ejecuta el siguiente comando en la terminal:

    echo "replace propagandist =>./propagandist" >> go.mod

    Importante: Este comando agrega una directiva replace a tu archivo go.mod. Esto es crucial porque le dice a Go que el paquete propagandist debe obtenerse del directorio local ./propagandist en lugar de intentar descargarlo de un repositorio remoto. Debes ejecutar este comando en tu terminal, lo que agregará la línea replace propagandist =>./propagandist a tu archivo go.mod. No escribas directamente esta línea en el archivo manualmente.

  4. Escribe el siguiente código en pacExercise.go para importar y usar el paquete propagandist:

    package main
    
    import (
        "fmt"
        "propagandist"
    )
    
    func main() {
        fmt.Println(propagandist.Shout) // Access the public variable
    }
    • Este código importa el paquete fmt para imprimir salida y el paquete propagandist.
    • Luego accede a la variable pública Shout del paquete propagandist utilizando propagandist.Shout.
  5. Ejecuta el programa:

    go mod tidy
    go run pacExercise.go

    El comando go mod tidy asegura que tu archivo go.mod se actualice con cualquier nueva dependencia. El comando go run pacExercise.go compila 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.

  1. Modifica pacExercise.go para utilizar importaciones agrupadas:

    package main
    
    import (
        "fmt"
        "propagandist"
    )
    
    func main() {
        fmt.Println(propagandist.Shout)
    }

    En el fragmento de código anterior, los paquetes fmt y propagandist se importan dentro de un solo bloque import encerrado 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.

  2. Ejecuta el programa para confirmar que sigue funcionando:

    go run pacExercise.go

    El 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.

  1. Modifica pacExercise.go para utilizar una importación con punto para fmt:

    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 paquete fmt directamente sin el prefijo fmt..
  • Por ejemplo, se utiliza Println en lugar de fmt.Println.
  1. Ejecuta el programa:

    go run pacExercise.go

    Salida 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.

  1. Modifica pacExercise.go para dar el alias io al paquete fmt:

    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 alias io para el paquete fmt.
    • Ahora, se utiliza io.Println en lugar de fmt.Println.
  2. 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.

  1. Modifica pacExercise.go para incluir una importación anónima del paquete time:

    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 paquete time se ejecutará cuando se ejecute este programa. El paquete time no tiene efectos secundarios particulares visibles aquí; sin embargo, muchos paquetes utilizan esto para registrar controladores de base de datos o configuraciones.
  2. Ejecuta el programa:

    go run pacExercise.go

    Salida esperada:

    I Love LabEx

Resumen

En este laboratorio, has aprendido:

  1. Cómo crear y definir paquetes personalizados en Go, encapsulando código reutilizable.
  2. La diferencia entre identificadores públicos (exportados) y privados (no exportados) y cómo afectan la accesibilidad.
  3. 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.
  4. 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:

  1. How to create and define custom packages in Go, encapsulating reusable code.
  2. The difference between public (exported) and private (unexported) identifiers and how they impact accessibility.
  3. 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.
  4. The role of the init() function in packages and how anonymous imports can trigger its execution.
  5. 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

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.