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.
Top comments (0)