Información sobre los paquetes
Los paquetes en Go son como bibliotecas o módulos en otros lenguajes de programación. Puede empaquetar el código y reutilizarlo en otra parte. El código fuente de un paquete se puede distribuir en más de un archivo .go
. Hasta ahora, hemos escrito el paquete main
y hemos hecho algunas referencias a otros paquetes nativos.
En esta sección, aprenderá qué es un paquete. También obtendrá información sobre cómo crear uno y cómo consumir paquetes externos.
Paquete principal
Como habrá observado, incluso el programa más sencillo de Go debe formar parte de un paquete. Normalmente, el paquete predeterminado es el paquete main
, el que hemos usado hasta ahora. Si un programa forma parte del paquete main
, Go genera un archivo binario. Cuando se ejecuta ese archivo, se llama a la función main()
.
En otras palabras, cuando se usa el paquete main
, el programa genera un archivo ejecutable independiente. Pero cuando un programa forma parte de un paquete que no es main
, Go no genera un archivo binario, Genera un archivo de almacenamiento de paquetes (un archivo que tiene la extensión .a
).
En Go, los nombres de paquetes siguen una convención. Un paquete usa la última parte de su ruta de acceso de importación como nombre. Por ejemplo, la biblioteca estándar de Go contiene un paquete denominado math/cmplx
, que proporciona código útil para trabajar con números complejos. La ruta de acceso de importación de este paquete es math/cmplx
y se importa de la siguiente forma:
import "math/cmplx"
Para hacer referencia a los objetos del paquete, use el nombre del paquete, cmplx
, de la siguiente forma:
cmplx.Inf()
Vamos a crear un paquete.
Creación de un paquete
Cree un nuevo directorio llamado calculator
en el directorio $GOPATH/src
. Cree un archivo llamado sum.go
. El árbol del directorio debe ser similar al siguiente:
src/
calculator/
sum.go
Inicialice el archivo sum.go
con el nombre del paquete:
package calculator
Ahora puede empezar a escribir las funciones y las variables del paquete. A diferencia de otros lenguajes de programación, Go no proporciona las palabras clave public
o private
para indicar si se puede llamar a una variable o a una función desde fuera o dentro del paquete. Pero Go sigue dos reglas simples:
- Si quiere que algo sea privado, escriba su nombre con la primera letra en minúscula.
- Si quiere que algo sea público, escriba su nombre con la primera letra en mayúscula.
Vamos a agregar el siguiente código al paquete "calculator" que estamos creando:
package calculator
var logMessage = "[LOG]"
// Version of the calculator
var Version = "1.0"
func internalSum(number int) int {
return number - 1
}
// Sum two integer numbers
func Sum(number1, number2 int) int {
return number1 + number2
}
Vamos a fijarnos en algunas cosas de este código:
- Solo se puede llamar a la variable
logMessage
desde dentro del paquete. - Se puede acceder a la variable
Version
desde cualquier lugar. Se recomienda incluir un comentario para describir el propósito de la variable. Esta descripción es útil para cualquier persona que use el paquete. - Solo se puede llamar a la función
internalSum
desde dentro del paquete. - Se puede acceder a la función
Sum
desde cualquier lugar. Se recomienda incluir un comentario para describir el propósito de la función.
Para confirmar que todo funciona, puede ejecutar el comando go build
en el directorio calculator
. Si lo hace, observe que no se genera ningún archivo binario ejecutable.
Creación de un módulo
Ha agrupado la funcionalidad de "calculator" en un paquete. Ahora es el momento de agrupar el paquete en un módulo. Los módulos de Go normalmente contienen paquetes que ofrecen funcionalidad relacionada. El módulo del paquete especifica el contexto que necesita Go para ejecutar el código que ha agrupado. Esta información contextual incluye la versión de Go para la que se ha escrito el código.
Además, los módulos ayudan a otros desarrolladores a hacer referencia a versiones específicas del código y facilitan el trabajo con dependencias. Otra ventaja es que el código fuente del programa no tiene que existir estrictamente en el directorio $GOPATH/src
. Sin esta restricción, resulta más cómodo trabajar con diferentes versiones de paquetes en otros proyectos al mismo tiempo.
Por tanto, para crear un módulo para el paquete calculator
, ejecute el siguiente comando en el directorio raíz ($GOPATH/src/calculator
):
go mod init github.com/myuser/calculator
Después de ejecutar este comando, github.com/myuser/calculator
se convierte en el nombre del módulo. Usará ese nombre para hacer referencia al paquete en otros programas. El comando también crea un nuevo archivo denominado go.mod
. Por último, el árbol del directorio ahora debería similar a este:
src/
calculator/
go.mod
sum.go
Por otro lado, el contenido del archivo go.mod
debería ser similar al siguiente código (aunque la versión de Go podría ser diferente):
module github.com/myuser/calculator
go 1.14
Para hacer referencia al paquete calculator
en otros programas, debe importarlo usando el nombre del módulo. En este caso, su nombre es github.com/myuser/calculator
. Veamos ahora un ejemplo de cómo usar este paquete.
Nota:
Históricamente, la administración de dependencias en Go nunca ha sido fácil. El sistema de administración de dependencias sigue siendo un trabajo en curso. Si quiere obtener más información sobre los módulos, consulte esta serie de publicaciones en el blog de Go.
Referencia a un paquete local (un módulo)
Ahora vamos a usar el paquete. Continuaremos con la aplicación de ejemplo que hemos usado hasta ahora. Esta vez, en lugar de tener la función sum
en el paquete main
, vamos a usar la función que hemos creado anteriormente en el paquete calculator
.
La estructura de árbol del archivo ahora debería ser similar a la siguiente:
src/
calculator/
go.mod
sum.go
helloworld/
main.go
Usaremos este código para el archivo $GOPATH/src/helloworld/main.go
:
package main
import (
"fmt"
"github.com/myuser/calculator"
)
func main() {
total := calculator.Sum(3, 5)
fmt.Println(total)
fmt.Println("Version: ", calculator.Version)
}
Observe que la instrucción "import" usa el nombre del paquete que ha creado: calculator
. Para llamar a la función Sum
desde ese paquete, debe incluir el nombre del paquete como calculator.Sum
. Por último, ahora también tiene acceso a la variable Version
. Puede llamar a la variable de esta forma: calculator.Version
.
Si intenta ejecutar el programa ahora, no funcionará. Debe indicarle a Go que está usando módulos para hacer referencia a otros paquetes. Para ello, ejecute este comando en el directorio $GOPATH/src/helloworld
:
go mod init helloworld
En el comando anterior, helloworld
es el nombre del proyecto. Este comando crea un nuevo archivo go.mod
, por lo que ahora el árbol del directorio tiene el siguiente aspecto:
src/
calculator/
go.mod
sum.go
helloworld/
go.mod
main.go
Al abrir el archivo go.mod
, debería ver algo parecido al siguiente código (aunque la versión de Go podría ser diferente):
module helloworld
go 1.14
Como está haciendo referencia a una copia local del módulo, debe informar a Go de que no quiere usar una ubicación remota. De este modo, debe modificar manualmente el archivo go.mod
para que incluya la referencia, tal y como se muestra a continuación:
module helloworld
go 1.14
require github.com/myuser/calculator v0.0.0
replace github.com/myuser/calculator => ../calculator
La palabra clave replace
especifica el uso de un directorio local en lugar de una ubicación remota para el módulo. En este caso, los programas helloworld
y calculator
se encuentran en $GOPATH/src
, por lo que la ubicación es simplemente ../calculator
. Si el origen del módulo se encontrara en una ubicación diferente, definiría la ruta de acceso local aquí.
Ejecute el programa mediante este comando:
go run main.go
La salida debería ser similar a la siguiente:
8
Version: 1.0
Desafío 1
¿Qué ocurre si intenta llamar a la variable logMessage
o a la función internalSum
del paquete calculator
en la aplicación principal? ¿Funciona? Pruébalo
Solución del desafío:
package main import ( "fmt" "github.com/myuser/calculator" ) func main() { total := calculator.internalSum(5) fmt.Println(total) fmt.Println("Version: ", calculator.logMessage) }
Publicación de un paquete
Publicar un paquete de Go es bastante sencillo. Solo tiene que hacer que el código fuente del paquete esté disponible públicamente. La mayoría de los desarrolladores usan GitHub para que los paquetes estén disponibles para el público, por lo que a veces encontrará referencias a github.com
en instrucciones de importación.
Por ejemplo, si quiere publicar el paquete calculator
en su cuenta de GitHub, debe crear un repositorio denominado calculator
. La dirección URL debería tener un aspecto similar al siguiente:
https://github.com/myuser/calculator
Tendrá que crear una versión de los paquetes etiquetando el repositorio de la siguiente manera:
git tag v0.1.0
git push origin v0.1.0
Los desarrolladores que quieran usar el paquete (incluido usted) harán referencia a él de esta forma:
import "github.com/myuser/calculator"
Vamos a profundizar más en cómo hacer referencia a paquetes de terceros.
Referencia a paquetes externos (de terceros)
A veces, los programas necesitan hacer referencia a paquetes escritos por otros desarrolladores. Normalmente, esos paquetes están disponibles en GitHub. Las siguientes instrucciones para hacer referencia a paquetes de terceros funcionan tanto si va a desarrollar un paquete (uno distinto de main
) como un programa independiente (el paquete main
).
Vamos a agregar una referencia al paquete rsc.io/quote
:
package main
import (
"fmt"
"github.com/myuser/calculator"
"rsc.io/quote"
)
func main() {
total := calculator.Sum(3, 5)
fmt.Println(total)
fmt.Println("Version: ", calculator.Version)
fmt.Println(quote.Hello())
}
Si usa Visual Studio Code, el archivo go.mod
se actualiza al guardar el archivo. Ahora tiene esta apariencia:
module helloworld
go 1.14
require (
github.com/myuser/calculator v0.0.0
rsc.io/quote v1.5.2
)
replace github.com/myuser/calculator => ../calculator
Observe cómo rsc.io/quote
hace referencia a una versión específica del paquete. Cuando necesite actualizar las dependencias de su programa, deberá cambiar la versión aquí.
Ejecute el programa de nuevo mediante este comando:
go run main.go
La salida debe ser similar a esta:
8
Version: 1.0
Hello, world.
Todas las referencias futuras a paquetes de terceros deberán incluirse en el archivo go.mod
. Al ejecutar o compilar la aplicación, Go descargará todas sus dependencias.