Introducci贸n
Despu茅s de la versi贸n 1.20, Go lanza la versi贸n 1.21 con algunas peque帽as novedades para explotar un poco m谩s el lenguaje, como siempre la nueva versi贸n tiene retrocompatibilidad con versiones anteriores, por lo que cambiar a la nueva versi贸n no deber铆a impactar en lo que ya tengamos hecho. Sin m谩s vamos a revisar cuales son las novedades en esta versi贸n:
Cambios en el lenguaje
Min y Max
En esta nueva versi贸n de Go encontramos funciones nuevas integradas como min y max, el cual toma un listado de valores y los compara devolviendo m铆nimo o m谩ximo respectivamente.
package main
import "fmt"
func main() {
x := 10
y := 15
mn := min(x, y) // m is the smaller of x and y
fmt.Printf("The min is %d \n", mn)
mx := max(x, y, 10) // m is the larger of x and y but at least 10
fmt.Printf("The max is %d \n", mx)
c := max(1, 2.0, 10) // c == 10.0 (floating-point kind)
fmt.Printf("The max is %f \n", c)
f := max(0, float32(x)) // type of f is float32
fmt.Printf("The max is %f \n", f)
// var s []string
// _ = min(s...)// invalid: slice arguments are not permitted
t := max("", "foo", "bar") // t == "foo" (string kind)
fmt.Printf("The max is %s \n", t)
}
Clear
Otra novedad de la nueva versi贸n de Go, es la funci贸n clear
package main
import "fmt"
func main() {
var mapToClear = map[string]int{"k1": 1, "k2": 2, "k3": 3}
clear(mapToClear) // Elimina todos los pares Key-Value (len(m) == 0)
fmt.Printf("%v \n", mapToClear)
var arr = []int{1, 2, 3, 4}
clear(arr) // Vuelve todos los elementos al valor Zero del tipo
fmt.Printf("%v \n", arr)
/*
var t = struct {
// Name string // Dato invalido para limpiar
mapToClear map[string]int
}{
// Name: "test",
mapToClear: map[string]int{"k1": 1, "k2": 2, "k3": 3},
}
clear(t) // No se puede hacer esto, tira un error ya que t debe ser del tipo map o slice
*/
}
Otras cositas del lenguaje
En cuanto a los gen茅ricos, se hicieron mejoras en cuanto a la inferencia de los tipos. Ahora se incluye una explicaci贸n sobre el proceso y como funciona en la documentaci贸n oficial.
Algo que planean hacer, que esta incluido en la version 1.21 de Go como experimental
, es arreglar la captura de variables en los ciclos for
, para eso recomiendan ir al caso escrito en LoopvarExperiment
Novedades de la SDK
Paquete log/slog
una de las cositas m谩s interesantes que sum贸 esta nueva versi贸n es el nuevo paquete log/slog para logging, el cual agrega funcionalidades a nuestro logging sin necesidad de sumar una librer铆a:
package main
import (
"log"
"log/slog"
)
func main() {
slog.Info("hello", "count", 3)
// 2009/11/10 23:00:00 INFO hello count=3
log.Println("hello", "count", 3)
// 2009/11/10 23:00:00 hello count 3
slog.Info("hello", "count", 1)
// 2009/11/10 23:00:00 INFO hello count=1
slog.Error("hello", "count", 2)
// 2009/11/10 23:00:00 ERROR hello count=2
slog.Warn("hello", "count", 3)
// 2009/11/10 23:00:00 WARN hello count=3
slog.Debug("hello", "count", 4)
// 2009/11/10 23:00:00 DEBUG hello count=4
// Print as json
h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelDebug})
slog.SetDefault(slog.New(h))
slog.Debug("it's a debug log")
}
Paquete slice
Nuevo paquete slice para manejo de slices justamente, esta incluye funcionalidades interesantes como m茅todos de ordenamiento o de b煤squedas:
package main
import (
"fmt"
"slices"
)
func main() {
arr := []int{8, 2, 4, 5, 1}
slices.Sort(arr) // Es mutable, por lo que cambia el array original
fmt.Println(arr) // [1 2 4 5 8]
index, found := slices.BinarySearch(arr, 2)
fmt.Println(found, index) // true 1
}
Paquete maps
Tambien se suma un nuevo paquete maps para los mapas pero con menos funciones:
package main
import (
"fmt"
"maps"
)
func main() {
mapEx := map[string]int{"k1": 1, "k2": 2}
mapClone := maps.Clone(mapEx)
fmt.Println(mapClone) // map[k1:1 k2:2]
equal := maps.Equal(mapEx, mapClone)
fmt.Println(equal) // true
}
Paquete cmp
Tambien se agrega un nuevo paquete cmp para comparar elementos:
package main
import (
"cmp"
"fmt"
)
func main() {
// -1 if x is less than y,
// 0 if x equals y,
// +1 if x is greater than y.
x := 5
y := 10
res := cmp.Compare(x, y)
fmt.Println(res) // -1
res = cmp.Compare(y, x)
fmt.Println(res) // 1
res = cmp.Compare(5, x)
fmt.Println(res) // 0
isLess := cmp.Less(5, x)
fmt.Println(isLess) // false
isLess = cmp.Less(x, y)
fmt.Println(isLess) // true
}
Profile Guided Optimization
La herramienta Profile Guided Optimization (PGO) anunciada en la versi贸n 1.20 ahora est谩 disponible sin necesidad de habilitarla. Con esta herramienta vamos a poder construir paquetes m谩s optimizados. Incluso se ha medido el impacto en varios programas y se ve mejoras del 2% al 7%.
Mejoras en la performance
Adem谩s de lo mencionado en PGO, podemos ver:
- El compilador de go fue reconstruido en la nueva versi贸n con PGO habilitado, lo que logr贸 hacerlo 2-4% m谩s r谩pido dependiendo del sistema que lo ejecute.
- Debido a la mejora en el Garbage Collector, se detecta una reducci贸n del 40% en la latencia de cola.
- Ahora la recolecci贸n de runtime/trace ahora reduce el costo para arquitectura arm64 y amd64.
Conclusi贸n
Estas son algunas de las novedades que podemos detectar de la nueva versi贸n de go, para m谩s detalle puede ir a leer el blog oficial en https://go.dev/blog/go1.21. Espero les ayude este resumen a poder comprenderlo.