Cómo escribir funciones auxiliares genéricas con Go 1.18

May 10 2022
Un enfoque genérico para verificar si un elemento está presente en una matriz/rebanada
Hace unos días necesitaba verificar si una matriz contiene un valor específico. Normalmente esta es una tarea sencilla y puedes usar una función predefinida desde el propio lenguaje de programación.
El Gopher fue dibujado por Egon Elbre.

Hace unos días necesitaba verificar si una matriz contiene un valor específico. Normalmente esta es una tarea sencilla y puedes usar una función predefinida desde el propio lenguaje de programación. En Go, desafortunadamente, tienes que crearlo tú mismo. Pero no te preocupes. Hoy construiremos una función que verifica si existe un elemento en una matriz. Así que abróchate el cinturón y vámonos.

Introducción

Una última cosa antes de comenzar. En nuestra solución necesitamos genéricos. Por lo tanto, debemos usar al menos la versión 1.18 de Golang. Afortunadamente, Golang lanzó la versión oficial 1.18 hace unas semanas, que incluye genéricos .

Enfoque

Nuestra intención debe ser clara. Entonces, ¿cuál es nuestro objetivo? Es bastante simple. Queremos una función a la que se le pase una matriz y un valor y devuelva verdadero si la matriz contiene el valor y falso si falta el valor.

Solución

Una solución sería crear una función en la que establezcamos los tipos de propiedades de forma estática. En la función, simplemente iteramos sobre la matriz y vemos si alguno de los valores de la matriz es igual a nuestro elemento.

Funciona bien. Sólo tenemos un problema con este enfoque. Imagine que para muchas matrices con diferentes tipos necesitamos verificar si una matriz contiene un valor. Para archivar esto, necesitamos crear una nueva función para cada tipo. Esto conduce a una base de código muy detallada y duplicada. Afortunadamente para nosotros, Golang introdujo varios tipos genéricos diferentes hace unos meses. En el próximo capítulo, podemos usar uno de ellos para hacer que nuestra solución sea un poco más flexible.

Mejoras

Para nuestro caso de uso, necesitamos el tipo genérico "comparable".
(Si desea saber más sobre los genéricos, puedo recomendarle el siguiente artículo ). Como puede ver a continuación, debemos escribir el nombre de nuestra T genérica entre paréntesis justo después del nombre de la función y asignarle el tipo "comparable". También le damos a ambos argumentos el tipo T. De esta manera, cuando llamamos a la función, podemos especificar qué tipo de matriz y elemento queremos comparar.

Para usarlo, tenemos que hacer la siguiente llamada de función:
Contains[string](["bar", "foo"], "foo").

La palabra "cadena" dentro de los corchetes antes del paréntesis es donde especificamos el tipo de nuestra matriz y el valor.

Punto de referencia

Ahora tenemos dos soluciones diferentes. Uno donde establecemos el tipo de los dos argumentos en la función misma. Y uno donde establecemos el tipo en la llamada a la función. Pero, ¿qué solución es más eficaz? y se nota la diferencia?

Para simplificar los genéricos, puede pensar en ellos como un tipo de reflejo fácil de usar. Normalmente, esto debería conducir a una diferencia de rendimiento entre estas dos funciones. Pero veamos:

go test -bench=”BenchmarkContains” -run=^# -benchtime=10000x

      
                
Benchmark Contains Functions

Pensamientos finales

Espero que el enfoque para verificar si una matriz contiene un valor determinado haya sido interesante y útil. Si tienes otra solución, algo que comentar o dudas, sería genial que lo dejaras en los comentarios. Te veo pronto.

PD: Este es el primer artículo de una nueva serie que tengo planeada. En las próximas semanas, analizaré varias funciones auxiliares genéricas, puntos de referencia interesantes y características útiles en todo el mundo de los viajes.

© Copyright 2021 - 2022 | unogogo.com | All Rights Reserved