DEV Community

Gino Luraschi
Gino Luraschi

Posted on

Novedades en Go 1.21 馃殌

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)
}
Enter fullscreen mode Exit fullscreen mode

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
    */
}

Enter fullscreen mode Exit fullscreen mode

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")
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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)