Cómo escribir código Go
Introducción
Este documento muestra el desarrollo de un sencillo paquete Go e introduce la herramienta go, la manera estándar para descargar, construir e instalar paquetes y órdenes Go.
La herramienta go
requiere que organices tu código en una manera
específica. Por favor lee cuidadosamente este documento. Este explica la
manera más sencilla de configurar y ejecutar tu instalación de Go.
Disponemos de una explicación similar en video (en inglés).
Organizando el código
Ambiente de trabajo
La herramienta go
está diseñada para trabajar con código de fuente
abierta mantenido en repositorios públicos. Aunque no es necesario
publicar tu código, el modelo para configurar el ambiente de trabajo es
igual si lo haces o no.
El código Go se debe mantener dentro de un ambiente de trabajo. Un ambiente de trabajo es una jerarquía de directorios con tres ramas en su raíz:
src
contiene los archivos de código fuente Go organizados en paquetes (un paquete por directorio),pkg
contiene objetos paquete, ybin
contiene las órdenes ejecutables.
La herramienta go
construye paquetes fuente e instala los binarios
resultantes a los directorios pkg
y bin
.
El subdirectorio src
típicamente contiene múltiples repositorios de
control de versiones (tal como Git o Mercurial) que siguen la pista al
código fuente del desarrollo de uno o más paquetes.
Para darte una idea de cómo se ve un ambiente de trabajo en la práctica, aquí tienes un ejemplo:
bin
hola # orden ejecutable
yasalio # orden ejecutable
pkg
linux_amd64
github.com/gitnacho/ejemplo
utilcadenas.a # objecto paquete
src
github.com/gitnacho/ejemplo
.git/ # metadatos del repositorio git
hola
hola.go # fuente de la orden
yasalio
main.go # fuente de la orden
main_test.go # fuente de la prueba
utilcadenas
reverso.go # fuente del paquete
reverso_test.go # fuente de la prueba
Este ambiente de trabajo contiene un repositorio (ejemplo
) que comprende
dos órdenes (hola
y yasalio
) y una biblioteca (utilcadenas
).
Un ambiente de trabajo típico debería tener varios repositorios fuente conteniendo muchos paquetes y órdenes. La mayoría de los programadores Go mantienen todo su código fuente y dependencias de Go en un único ambiente de trabajo.
Las órdenes y bibliotecas se construyen de diferentes clases de paquetes fuente. Hablaremos sobre esta distinción más adelante.
La variable de entorno GOPATH
La variable de entorno GOPATH
especifica la ubicación de tu ambiente de
trabajo. Probablemente esta puede ser la única variable de entorno que
necesitarás configurar cuando desarrollas código Go.
Para empezar, crea un directorio para tu ambiente de trabajo y configura
GOPATH
consecuentemente. Tu ambiente de trabajo se puede localizar en
dónde quieras, no obstante, en este documento utilizaremos $HOME/go
. Ten
en cuenta que esta no debe ser la misma ruta que tu instalación de Go.
$ mkdir $HOME/go
$ export GOPATH=$HOME/go
Por comodidad, añade el subdirectorio bin
del ambiente de trabajo a tu
PATH
:
$ export PATH=$PATH:$GOPATH/bin
Rutas de paquetes
A los paquetes de la biblioteca estándar se les asignan rutas cortas tal
como "fmt"
y "http/net"
. Para tus propios paquetes, debes escoger una
ruta base que sea poco probable pueda colisionar con futuras adiciones a
la biblioteca estándar u otras bibliotecas externas.
Si mantienes tu código en algún repositorio fuente, entonces deberías
utilizar la raíz de ese repositorio fuente como tu ruta base. Por
ejemplo, si tu cuenta GitHub está en
github.com/usuario
, esa debería ser tu ruta base.
Ten en cuenta que no necesitas publicar tu código a un repositorio remoto antes de que lo puedas construir. solo es un buen hábito para organizar tu código como si algún día lo fueras a publicar. En la práctica puedes escoger cualquier nombre de ruta arbitrario, siempre y cuando sea único en la biblioteca estándar y en el ecosistema Go.
Utilizaremos github.com/usuario
como nuestra ruta base. Crea un
directorio dentro de tu ambiente de trabajo en el cual mantendrás el
código fuente:
$ mkdir -p $GOPATH/src/github.com/usuario
Tu primer programa
Para compilar y correr un sencillo programa, primero escoge una ruta para
el paquete (utilizaremos github.com/usuario/hola
) y crea un directorio
para el paquete correspondiente dentro de tu ambiente de trabajo:
$ mkdir $GOPATH/src/github.com/usuario/hola
Luego, crea un archivo llamado hola.go
dentro de ese directorio,
conteniendo el siguiente código Go.
package main
import "fmt"
func main() {
fmt.Printf("Hola, mundo.\n")
}
Ahora puedes construir e instalar el programa con la herramienta go
:
$ go install github.com/usuario/hola
Ten en cuenta que puedes ejecutar esta orden desde cualquier lugar en tu
sistema. La herramienta go
encuentra el código fuente buscando el
paquete github.com/usuario/hola
dentro del ambiente de trabajo
especificado por GOPATH
.
También puedes omitir la ruta del paquete si ejecutas go install
desde
el directorio del paquete:
$ cd $GOPATH/src/github.com/usuario/hola
$ go install
Estas instrucciones construyen la orden hola
, produciendo un ejecutable
binario. Esto instala el binario en el directorio bin
del ambiente de
trabajo como hola
(o, bajo Windows, hola.exe
). En nuestro ejemplo,
este será $GOPATH/bin/hola
, el cual está en $HOME/go/bin/hola
.
La herramienta go
solo producirá salida cuando ocurra un error, así que
si estas órdenes no producen ninguna salida es porque se han ejecutado
satisfactoriamente.
Ahora puedes ejecutar el programa escribiendo la ruta completa en la línea de órdenes:
$ $GOPATH/bin/hola
Hola, mundo.
O, suponiendo que añadíste $GOPATH/bin
a tu PATH
, solo escribe el
nombre del binario:
$ hola
Hola, mundo.
Si estás utilizando un sistema de control de versiones, ahora sería un buen momento para iniciar un repositorio, añadir los archivos y enviar tu primer entrega. Una vez más, este paso es opcional: no es necesario utilizar el control de versiones para escribir código Go.
$ cd $GOPATH/src/github.com/usuario/hola
$ git init
Inicia repositorio Git vacío en /home/user/go/src/github.com/usuario/hola/.git
$ git add hola.go
$ git commit -m "entrega inicial"
[master (root-commit) 0b4507d] entrega inicial
1 archivo cambió, 1 insercion(+)
crea modo 100644 hola.go
Dejamos el envío del código a un repositorio remoto como ejercicio para el lector.
Tu primer biblioteca
Vamos a escribir una biblioteca y a usarla desde el programa hola
.
De nuevo, el primer paso es escoger una ruta para el paquete (utilizaremos
github.com/usuario/utilcadenas
) y creamos el directorio del paquete:
$ mkdir $GOPATH/src/github.com/usuario/utilcadenas
A continuación, crea un archivo llamado reverso.go
en ese directorio con
el siguiente contenido.
// utilcadenas este paquete contiene útiles funciones para trabajar
// con cadenas de caracteres.
package utilcadenas
// Reverso invierte su argumento s dejándolo legible de izquierda
// a derecha.
func Reverso(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
Ahora, comprueba que el paquete compila con go build
:
$ go build github.com/usuario/utilcadenas
O, si estás trabajando en el directorio fuente del paquete, justo:
$ go build
Esto no producirá un archivo. Para ello, tienes que utilizar go install
,
que coloca el objeto paquete dentro del directorio pkg
del ambiente de
trabajo.
Después de confirmar la construcción del paquete utilcadenas
, modifica
tu hola.go
original (que está en $GOPATH/src/github.com/usuario/hola
)
para utilizarlo:
package main
import (
"fmt"
"github.com/usuario/utilcadenas"
)
func main() {
fmt.Printf(utilcadenas.Reverso("!oG ,aloH¡"))
}
Siempre que la herramienta go
instala un paquete o binario, también
instala todas las dependencias que tenga. Por lo tanto cuando instalas el
programa hola
$ go install github.com/usuario/hola
Automáticamente también instalará el paquete utilcadenas
.
Al ejecutar la nueva versión del programa, deberías ver un nuevo mensaje, invertido:
$ hola
¡Hola, Go!
Después de los pasos anteriores, tu ambiente de trabajo se parecerá a este:
bin
hola # orden ejecutable
pkg
linux_amd64/ # esto reflejará tu SO y arquitectura
github.com/usuario
utilcadenas.a # objecto paquete
src
github.com/usuario
hola
hola.go # fuente de la orden
utilcadenas
reverso.go # fuente del paquete
Ten en cuenta que go install
colocó el objeto utilcadenas.a
en un
directorio dentro de pkg/linux_amd64
que refleja tu directorio fuente.
Esto es a modo de que futuras invocaciones a la herramienta go
puedan
encontrar el objeto paquete y evitar recompilar innecesariamente el
paquete. La parte linux_amd64
está allí para ayudar en recompilaciones
cruzadas, y refleja el sistema operativo y arquitectura de tu sistema.
Las órdenes ejecutables se enlazan estáticamente; los objetos paquete no es necesario que estén presentes para ejecutar los programas Go.
Nombre de paquetes
La primer declaración en un archivo fuente de Go tiene que ser:
package nombre
Dónde nombre
es el nombre predeterminado del paquete para
importaciones. (Todos los archivos en un paquete tienen que utilizar el
mismo nombre
).
Una convención en Go es que el nombre del paquete es el último elemento de
la ruta de importación: el paquete importado como "crypto/rot13
" se
debería llamar rot13
.
Las órdenes ejecutables siempre tienen que usar package main
.
No hay ningún requisito para que los nombres de paquete sean únicos entre todos los paquetes enlazados a un solo binario, solo que las rutas de importación (sus nombres de archivo completos) sean únicos.
Ve Go eficiente para aprender más sobre las convenciones de nomenclatura en Go.
Probando
Go tiene una ligera plataforma de pruebas compuesta de la orden go test
y el paquete testing
.
Escribes una prueba creando un archivo con un nombre que termine en
_test.go
el cual contiene las funciones llamadas TestXXX
con la firma
func (t *testing.T)
. La plataforma de pruebas corre cada una de esas
funciones; si la función invoca a una función de fallo tal como t.Error
o t.Fail
, se considerada que la prueba falló.
Añade una prueba al paquete utilcadenas
creando el archivo
$GOPATH/src/github.com/usuario/utilcadenas/reverso_test.go
conteniendo
el siguiente código Go.
package utilcadenas
import "testing"
func TestReverso(t *testing.T) {
casos := []struct {
ingresada, deseada string
}{
{"Hola, mundo", "odnum ,aloH"},
{"Hola, 世界", "界世 ,aloH"},
{"", ""},
}
for _, c := range casos {
obtuve := Reverso(c.ingresada)
if obtuve != c.deseada {
t.Errorf("Reverso(%q) == %q, deseada %q", c.ingresada, obtuve, c.deseada)
}
}
}
Entonces corre la prueba con go test
:
$ go test github.com/usuario/utilcadenas
ok github.com/usuario/utilcadenas 0.165s
Como siempre, si estás corriendo la herramienta go
desde el directorio
del paquete, puedes omitir la ruta del paquete:
$ go test
ok github.com/usuario/utilcadenas 0.165s
Corre go help test y ve la documentación del paquete testing para más detalles.
Paquetes remotos
Una ruta de importación puede describir cómo obtener el código fuente del
paquete utilizando un sistema de control de versiones tal como Git o
Mercurial. La herramienta go
utiliza esta propiedad para automáticamente
descargar paquetes desde repositorios remotos. Por ejemplo, los
fragmentos de código descritos en este documento también están mantenidos
en un repositorio Git hospedado en Github,
github.com/gitnacho/ejemplo. Si
incluyes el URL del repositorio en la ruta de importación del paquete, go
get
lo descargará, construirá e instalará automáticamente:
$ go get github.com/gitnacho/ejemplo/hola
$ $GOPATH/bin/hola
¡Hola, ejemplos Go!
Si el paquete especificado no está presente en un ambiente de trabajo, go
get
lo colocará dentro del primer ambiente de trabajo especificado por
GOPATH
. (Si el paquete ya existe, go get
omitirá la descarga remota y
se comportará igual que go install
).
Después de emitir la orden go get
anterior, ahora el árbol de
directorios del ambiente de trabajo se debería parecer a este:
bin
hello # orden ejecutable
pkg
linux_amd64
github.com/gitnacho/ejemplo
utilcadenas.a # objeto paquete
github.com/usuario
utilcadenas.a # objecto paquete
src
github.com/gitnacho/ejemplo
.git/ # metadatos del repositorio Git
hola
hola.go # fuente de la orden
utilcadenas
reverso.go # fuente del paquete
reverso_test.go # fuente de pruebas
github.com/usuario
hola
hola.go # fuente de la orden
utilcadenas
reverso.go # fuente del paquete
reverso_test.go # fuente de pruebas
La orden hola
hospedada en Github depende del paquete utilcadenas
dentro del mismo repositorio. Las importaciones en el archivo hola.go
utilizan la misma convención de las rutas de importación, por lo tanto la
orden go get
también es capaz de localizar e instalar el paquete
dependiente.
import "github.com/gitnacho/ejemplo/utilcadenas"
Esta convención es la manera más fácil de permitir que tus paquetes Go estén disponibles para que otros los utilicen. El Wiki de Go y godoc.org proporcionan listas de proyectos Go externos.
Para más información sobre el uso de repositorios remotos con la
herramienta go
, ve
go help importpath.
Algo más
Suscríbete a la lista de correo golang-announce para recibir notificaciones de cuándo se liberará una nueva versión estable de Go.
Ve Go eficiente para ver algunos consejos sobre cómo escribir claro e idiomático código Go.
Toma Un paseo por Go para aprender adecuadamente el lenguaje.
Visita la página de documentación para un conjunto de artículos que profundizan en el lenguaje Go, sus bibliotecas y herramientas.
Consiguiendo ayuda
Para ayuda en tiempo real, pregunta a los serviciales gophers en el canal
#go-nuts
del servidor IRC Freenode.
La lista de correo oficial para discusión del lenguaje Go es Go Nuts.
Reporta fallos utilizando el Gestor de incidencias Go.
En su mayor parte este libro se reproduce a partir del trabajo creado y compartido por Google traducido al Español y se usa de acuerdo a los términos descritos en la Licencia Creative Commons 3.0 Attribution.