1. Code
  2. Coding Fundamentals

12 Indispensable Go Paquetes y Librerías

Scroll to top

Spanish (Español) translation by James (you can also view the original English article)

Go es un lenguaje asombroso con mucho ímpetu, y se centra en la simplicidad. Este enfoque es evidente en su biblioteca estándar, que proporciona todo lo necesario, pero no mucho más.

Afortunadamente, Go tiene una vibrante comunidad que crea y comparte un montón de librerías de terceros. En este tutorial, te introduzco a 12 de Go mejores paquetes y bibliotecas. Algunas de ellas tienen alcance relativamente estrecho y pueden agregarse a cualquier proyecto, mientras que otros son grandes proyectos que usted puede incorporar en sistemas distribuidos a gran escala, masivos.

Awesome Go

Antes de zambullirse en las bibliotecas de sí mismos, permítanme presentarles a Awesome Go, una lista muy activa y curada de Go bibliotecas y otros recursos. Debe visitar de vez en cuando y comprobar lo nuevo.

1. Set de Golang

Go tiene arreglos de discos, láminas y mapas, pero no tiene una estructura de datos del sistema. Puede imitar un conjunto con un mapa de bools, pero es bueno tener un tipo de datos reales con las operaciones de derecha y semántica. Esto es donde golang-set. Aquí es un ejemplo básico de crear un nuevo conjunto, agregar elementos y pruebas para ser miembro:

1
package main
2
3
import (
4
    "fmt"
5
  "github.com/deckarep/golang-set"
6
)
7
8
9
func main() {
10
	basicColors := mapset.NewSet()
11
	basicColors.Add("Red")
12
	basicColors.Add("Blue")
13
	basicColors.Add("Green")
14
15
	if basicColors.Contains("Green") {
16
		fmt.Println("Yay! 'Green' is a basic color")
17
	} else {
18
		fmt.Println("What a disappointment! 'Green' is not a basic color")
19
	}
20
21
22
	if basicColors.Contains("Yellow") {
23
		fmt.Println("Yay! 'Yellow' is a basic color")
24
	} else {
25
		fmt.Println("What a disappointment! 'Yellow' is not a basic color")
26
	}
27
}
28
29
Output:
30
31
Yay! 'Green' is a basic color
32
What a disappointment! 'Yellow' is not a basic color

Observe que el nombre del paquete es "mapset". Además de lo básico, es realizar todos las operaciones Unión, intersección y diferencia. Usted también puede iterar sobre los valores:

1
package main
2
3
import (
4
    "fmt"
5
	"github.com/deckarep/golang-set"
6
)
7
8
9
func main() {
10
	basicColors := mapset.NewSet()
11
	basicColors.Add("Red")
12
	basicColors.Add("Blue")
13
	basicColors.Add("Green")
14
15
	otherColors := mapset.NewSetFromSlice([]interface{}{"Orange", "Yellow", "Indigo", "Violet"})
16
	rainbowColors := basicColors.Union(otherColors)
17
18
	for color := range rainbowColors.Iterator().C {
19
		fmt.Println(color)
20
	}
21
}

2. Color

Continuemos con el tema de color. Al escribir programas de línea de comandos, es útil utilizar colores para destacar mensajes importantes o distinguir entre errores, éxitos y advertencias.

El paquete de color da una manera fácil de añadir color a sus programas (ver lo que hice allí?). ¡Utiliza códigos de escape ANSII y soporta Windows también! Aquí está un ejemplo rápido:

1
package main
2
3
import (
4
    "github.com/fatih/color"
5
)
6
7
func main() {
8
	color.Red("Roses are red")
9
	color.Blue("Violets are blue")
10
}

Las ayudas del paquete de color mezclando colores con los colores de fondo, estilos como negrita o cursiva y riego color con salida sin color.

1
package main
2
3
import (
4
    "github.com/fatih/color"
5
	"fmt"
6
)
7
8
func main() {
9
	minion := color.New(color.FgBlack).Add(color.BgYellow).Add(color.Bold)
10
	minion.Println("Minion says: banana!!!!!!")
11
12
	m := minion.PrintlnFunc()
13
	m("I want another banana!!!!!")
14
15
	slantedRed := color.New(color.FgRed, color.BgWhite, color.Italic).SprintFunc()
16
	fmt.Println("I've made a huge", slantedRed("mistake"))
17
}

El paquete de color tiene otras características útiles. Seguir adelante y explorar más.

3. Now

Now es un paquete muy simple que proporciona un contenedor de comodidad para el paquete de tiempo estándar y facilita trabajar con varias construcciones de fecha y hora en la época actual.

Por ejemplo, puede llegar el principio del minuto actual o al final del domingo más cercano a la hora actual. Aquí es cómo utilizar "Now":

1
package main
2
3
import (
4
    "github.com/jinzhu/now"
5
	"fmt"
6
)
7
8
func main() {
9
10
	fmt.Println("All the beginnings...")
11
	fmt.Println(now.BeginningOfMinute())
12
	fmt.Println(now.BeginningOfHour())
13
	fmt.Println(now.BeginningOfDay())
14
	fmt.Println(now.BeginningOfWeek())
15
	fmt.Println(now.BeginningOfMonth())
16
	fmt.Println(now.BeginningOfQuarter())
17
	fmt.Println(now.BeginningOfYear())
18
19
}
20
21
Output:
22
23
All the beginnings...
24
2017-06-04 16:59:00 -0700 PDT
25
2017-06-04 16:00:00 -0700 PDT
26
2017-06-04 00:00:00 -0700 PDT
27
2017-06-04 00:00:00 -0700 PDT
28
2017-06-01 00:00:00 -0700 PDT
29
2017-04-01 00:00:00 -0700 PDT
30
2016-12-31 23:00:00 -0800 PST

Puede también analizar tiempos y añadir sus propios formatos (que serán necesario actualizar los formatos conocidos). El tipo Now incorpora time.Time, así que puede usar métodos time.Time de tiempo directamente en objetos de Now.

4. Gen

La herramienta gen genera código para usted, en particular, que tipo de código que intenta paliar el vacío de no tener plantillas o genéricos en Go.

Anota los tipos con un comentario especial, y gen genera archivos de origen que se incluyen en el proyecto. No hay magia de tiempo de ejecución. Veamos un ejemplo. Aquí es un tipo de anotación.

1
// +gen slice:"Where,Count,GroupBy[int]"
2
type Person struct {
3
    Name string
4
	Age int
5
}

Ejecutando gen (Asegúrese de que esté en tu camino) genera person_slice.go:

1
// Generated by: gen
2
// TypeWriter: slice
3
// Directive: +gen on Person
4
5
package main
6
7
// PersonSlice is a slice of type Person. Use it where you would use []Person.
8
type PersonSlice []Person
9
10
// Where returns a new PersonSlice whose elements return true for func. See: https://clipperhouse.github.io/gen/#Where
11
func (rcv PersonSlice) Where(fn func(Person) bool) (result PersonSlice) {
12
    for _, v := range rcv {
13
		if fn(v) {
14
			result = append(result, v)
15
		}
16
	}
17
	return result
18
}
19
20
// Count gives the number elements of PersonSlice that return true for the passed func. See: http://clipperhouse.github.io/gen/#Count
21
func (rcv PersonSlice) Count(fn func(Person) bool) (result int) {
22
	for _, v := range rcv {
23
		if fn(v) {
24
			result++
25
		}
26
	}
27
	return
28
}
29
30
// GroupByInt groups elements into a map keyed by int. See: http://clipperhouse.github.io/gen/#GroupBy
31
func (rcv PersonSlice) GroupByInt(fn func(Person) int) map[int]PersonSlice {
32
	result := make(map[int]PersonSlice)
33
	for _, v := range rcv {
34
		key := fn(v)
35
		result[key] = append(result[key], v)
36
	}
37
	return result
38
}

El código proporciona LINQ-like métodos para operar en el tipo de PersonSlice. Es fácil de entender y muy bien documentado.

Aquí es cómo usarlo. En la función principal, se define un PersonSlice. La función age() selecciona el campo de la edad de su argumento Person. La función GroupByInt() genera la función age() y vuelve la gente de la rebanada agrupada por su edad (34 es a Jim, pero 23 tiene Jane y Kyle).

1
package main
2
3
import (
4
    "fmt"
5
)
6
7
// +gen slice:"Where,Count,GroupBy[int]"
8
type Person struct {
9
	Name string
10
	Age int
11
}
12
13
func age(p Person) int {
14
	return p.Age
15
}
16
17
func main() {
18
	people := PersonSlice {
19
		{"Jim", 34},
20
		{"Jane", 23},
21
		{"Kyle", 23},
22
	}
23
24
	groupedByAge := people.GroupByInt(age)
25
26
	fmt.Println(groupedByAge)
27
}
28
29
30
Output:
31
32
map[34:[{Jim 34}] 23:[{Jane 23} {Kyle 23}]]

5. Gorm

Go es conocido por su carácter espartano. Programación de base de datos no es diferente. Las bibliotecas más populares de DB para ir son bastante bajo nivel. Gorm trae el mundo de Mapeo objeto-relacional para Go con las siguientes características:

  • Asociaciones (tiene uno, tiene muchos, pertenece, muchos a muchos, polimorfismo)
  • Devoluciones de llamada (antes y después de crear/guardar/actualizar/borrar/buscar)
  • Precarga (ansioso por carga)
  • Transacciones
  • Clave Primaria Compuesta
  • Constructor SQL
  • Migraciones Automatica
  • Registrador
  • Extensible, escribir Plugins basado en callbacks GORM

Pero no cubre todo. Si vienes desde Python, no esperes magia SQLAlchemy. Para más cosas de lujo, usted tendrá que ir un nivel más bajo. Aquí es un ejemplo de cómo usar Gorm con sqlite. Tenga en cuenta el gorm.Model incrustada en la estructura del producto.

1
package main
2
3
import (
4
    "github.com/jinzhu/gorm"
5
    _ "github.com/jinzhu/gorm/dialects/sqlite"
6
)
7
8
type Product struct {
9
  gorm.Model
10
  Code string
11
  Price uint
12
}
13
14
func main() {
15
  db, err := gorm.Open("sqlite3", "test.db")
16
  if err != nil {
17
    panic("failed to connect database")
18
  }
19
  defer db.Close()
20
21
  // Migrate the schema
22
  db.AutoMigrate(&Product{})
23
24
  // Create
25
  db.Create(&Product{Code: "L1212", Price: 1000})
26
27
  // Read
28
  var product Product
29
  db.First(&product, 1) // find product with id 1
30
  db.First(&product, "code = ?", "L1212")
31
32
  // Update - update product's price to 2000
33
  db.Model(&product).Update("Price", 2000)
34
35
  // Delete - delete product
36
  db.Delete(&product)

6. Goose

Una de las tareas más importantes cuando se trabaja con bases de datos relacionales es administrar el esquema. Modificando el esquema de DB se considera un cambio de "miedo" en algunas organizaciones. El paquete de Goose le permite realizar cambios de esquema y migraciones de datos incluso si es necesario. Puede goose up y goose down para ir hacia adelante y hacia atrás. Mente sus datos y asegúrese de que no Haz perdido o dañado.

Ganso obras de control de versiones el esquema y utilizando archivos de migración correspondientes a cada esquema. Los archivos de migración pueden ser comandos SQL o comandos Go. Este es un ejemplo de un archivo de migración de SQL que agrega una nueva tabla:

1
-- +goose Up
2
CREATE TABLE person (
3
    id int NOT NULL,
4
    name text,
5
    age int,
6
    PRIMARY KEY(id)
7
);
8
9
-- +goose Down
10
DROP TABLE person;

El -- +goose up y -- +goose down comentarios dicen goose qué hacer para mejorar o degradar el esquema.

7. Glide

Glide es un gestor de paquetes para ir. Bajo una sola GOPATH, pueden tener muchos programas que tienen dependencias contradictorias. La solución es que cada programa de administrar su propio directorio de proveedores de las dependencias del paquete. Glide ayuda con esta tarea.

Aquí están las características de Glide:

  • Soporte de paquetes de control de versiones incluyendo soporte semántico versión 2.0.0.
  • Soporte paquetes de aliasing (por ejemplo, para trabajar con horquillas de github).
  • Eliminar la necesidad de que las declaraciones de importación de descripciones.
  • Trabajar con todas las herramientas de Go.
  • Soporte todas las herramientas de VCS que Go apoya (git, bzr, hectogramo, svn).
  • Soporte custom plugins locales y globales.
  • Repositorio de almacenamiento en caché y caché de datos para mejorar el rendimiento.
  • Aplane las dependencias, las diferencias de versión y evitando la inclusión de un paquete varias veces.
  • Gestionar e instalar dependencias bajo demanda o vendored en su sistema de control de versión.

Las dependencias se almacenan en glide.yaml, y planeo proporciona varios comandos para manejar las dependencias:

1
     create, init       Initialize a new project, creating a 
2
                        glide.yaml file
3
     config-wizard, cw  Wizard that makes optional suggestions 
4
                        to improve config in a glide.yaml file.
5
     get                Install one or more packages into 
6
                        `vendor/` and add dependency to 
7
                        glide.yaml.
8
     remove, rm         Remove a package from the glide.yaml 
9
                        file, and regenerate the lock file.
10
     import             Import files from other dependency 
11
                        management systems.
12
     name               Print the name of this project.
13
     novendor, nv       List all non-vendor paths in a 
14
                        directory.
15
     rebuild            Rebuild ('go build') the dependencies
16
     install, i         Install a project's dependencies
17
     update, up         Update a project's dependencies
18
     tree               (Deprecated) Tree prints the 
19
                        dependencies of this project as a tree.
20
     list               List prints all dependencies that the 
21
                        present code references.
22
     info               Info prints information about this 
23
                        project
24
     cache-clear, cc    Clears the Glide cache.
25
     about              Learn about Glide
26
     mirror             Manage mirrors
27
     help, h            Shows a list of commands or help for 
28
                        one command

8. Ginkgo

Ginkgo es un framework de pruebas de BDD (Behavior Driven Development). Le permite escribir las pruebas en una sintaxis que se asemeja a Inglés y permitir a la gente menos técnica examinar las pruebas (y su producción) y verificar que coinciden con los requerimientos del negocio.

Algunos desarrolladores como este estilo de la especificación de prueba demasiado. Se integra con el paquete de prueba incorporado de ir y se combina a menudo con Gomega. Este es un ejemplo de un Ginkgo + Gomega prueba:

1
actual, err := foo()
2
Ω(err).Should(BeNil())
3
Ω(actual).ShouldNot(BeNil())
4
Ω(actual.result).Should(Equal(100))

9. Etcd

Etcd es una tienda confiable de clave y valor distribuida. El servidor se implementa en Go, y aunque cliente vaya interactúa con él gRPC.

Se centra en lo siguiente:

  • Simple: bien definida, orientada al usuario API (gRPC).
  • Seguro: automático TLS con autenticación de cliente cert opcional.
  • Rápido: entre 10.000 escrituras por segundo.
  • Confiable: correctamente distribuida utilizando balsa.

Aquí es un ejemplo de conexión con el servidor, colocando un valor y conseguirla, incluyendo tiempos de espera y limpieza.

1
func test_get() {
2
    cli, err := clientv3.New(clientv3.Config{
3
		Endpoints:   endpoints,
4
		DialTimeout: dialTimeout,
5
	})
6
	if err != nil {
7
		log.Fatal(err)
8
	}
9
	defer cli.Close()
10
11
	_, err = cli.Put(context.TODO(), "foo", "bar")
12
	if err != nil {
13
		log.Fatal(err)
14
	}
15
16
	ctx, cancel := context.WithTimeout(context.Background(), 
17
                                       requestTimeout)
18
	resp, err := cli.Get(ctx, "foo")
19
	cancel()
20
	if err != nil {
21
		log.Fatal(err)
22
	}
23
	for _, ev := range resp.Kvs {
24
		fmt.Printf("%s : %s\n", ev.Key, ev.Value)
25
	}
26
	// Output: foo : bar
27
}

10. NSQ

NSQ es una gran cola distribuida. Lo he utilizado con éxito como un bloque principal de construcción para sistemas distribuidos a gran escala. Estas son algunas de sus características:

  • La ayuda distribuidas topologías con ningún SPOF.
  • Horizontal escalable (no brokers, perfectamente añadir más nodos al clúster).
  • Baja latencia empuje basado en entrega de mensajes (rendimiento).
  • Combinación de equilibrio de carga y enrutamiento de mensajes de multidifusión de estilo.
  • Excel en streaming (alto rendimiento) y trabajo orientado a las cargas de trabajo (bajo rendimiento).
  • Sobre todo en la memoria (más allá de una agua marca alta mensajes transparente se guardan en el disco).
  • Servicio de detección de tiempo de ejecución para los consumidores encontrar productores (nsqlookupd).
  • Seguridad de capa de transporte (TLS).
  • Formato de datos independiente.
  • Algunas dependencias (fáciles de implementar) y sane, delimitado, configuración por defecto.
  • Protocolo TCP simple apoyo a bibliotecas de cliente en cualquier idioma.
  • Interfaz HTTP para estadísticas, acciones de la administración y los productores (biblioteca de cliente no es necesario para publicar).
  • Se integra con statsd para instrumentación en tiempo real.
  • Interfaz de administración de clúster robusto (nsqadmin).

Aquí es cómo publicar un mensaje en NSQ (manejo de errores se omite):

1
package main
2
3
import (
4
  "github.com/bitly/go-nsq"
5
)
6
7
func main() {
8
  config := nsq.NewConfig()
9
  p, _ := nsq.NewProducer("127.0.0.1:4150", config)
10
11
  p.Publish("topic", []byte("message"))
12
  p.Stop()
13
}

Y aquí está cómo consumir:

1
package main
2
3
import (
4
  "sync"
5
  "fmt"
6
  "github.com/bitly/go-nsq"
7
)
8
9
func main() {
10
  wg := &sync.WaitGroup{}
11
  wg.Add(1)
12
13
  config := nsq.NewConfig()
14
  q, _ := nsq.NewConsumer("topic", "channel", config)
15
  handler := nsq.HandlerFunc(func(message *nsq.Message) error {
16
      fmt.Printf("Got a message: %v", message)
17
      wg.Done()
18
      return nil
19
  })
20
  q.AddHandler(handler)
21
  q.ConnectToNSQD("127.0.0.1:4150")
22
  wg.Wait()
23
}

11. Docker

Docker es un nombre familiar ahora (si los miembros de su familia son en su mayoría gente de DevOps). No es consciente que el Docker es implementado en Go. Por lo general no utiliza Docker en el código, pero es un proyecto importante y merece ser reconocida como un proyecto de Go enormemente exitoso y popular.

12. Kubernetes

Kubernetes es una plataforma de orquestación de contenedor de código abierto para aplicaciones nativas de nube. Es otro sistema de monstruo distribuido en Go. Recientemente escribí un libro llamado Dominando Kubernetes donde ir en detalle sobre los aspectos más avanzados de Kubernetes. Desde el punto de vista del desarrollador vaya Kubernetes es muy flexible, y puede extender y personalizar mediante plugins.

Conclusión

Go es una gran lengua. Su filosofía de diseño es un lenguaje simple y accesible. Su biblioteca estándar no es tan completo como otros lenguajes como Python.

Se acercó la comunidad Go, y hay muchas bibliotecas de alta calidad que se pueden utilizar en sus programas. En este artículo, introduje las 12 bibliotecas. Le animo a buscar otras bibliotecas antes de saltar e implementar todo desde cero.