Haga clic en el azul "Flying Snow Ruthless" arriba para seguir mi cuenta oficial, establecer una estrella y leer el artículo lo antes posible.
En el lenguaje Go, el segmento y el mapa son tipos básicos comunes, a través de los cuales podemos usar datos fácilmente. Pero, ¿ha encontrado que para procesar estos dos tipos de datos, tiene que escribir muchas funciones de utilidad?
Por ejemplo, ¿encontrar la posición de un elemento a partir de un corte? Este tipo de búsqueda se divide en búsqueda anterior y búsqueda posterior.
Otro ejemplo, ¿conseguir todas las claves del mapa? o todos los valores?
Otro ejemplo son las funciones de mapa, reducción y filtro de las matrices de lenguaje JS, que son muy útiles en la programación, pero desafortunadamente la biblioteca estándar de Go no las proporciona.
Hay muchos más de estos ejemplos, y todos son funciones de utilidad comunes en nuestra programación, pero nuestro Go SDK no.
Pero, ¿qué tenemos que hacer? Una forma es escribir un conjunto de herramientas nosotros mismos para usar en proyectos, pero el mantenimiento de este conjunto de herramientas es otro problema y requiere mano de obra.
La segunda forma es utilizar una biblioteca de código abierto, que se haya probado, verificado y actualizado con frecuencia, por lo que se puede garantizar.
Debido a que encontramos problemas comunes, alguien creó una biblioteca de código abierto para que todos la usen. Este tipo de biblioteca de herramientas se basa en Go 1.18. Antes de Go 1.18, existe un go-funk bien conocido.
Nombre muy interesante, la dirección de Repo es https://github.com/thoas/go-funk. La introducción oficial es una biblioteca de herramientas de idioma Go:
Una biblioteca de utilidades Go moderna que proporciona ayudantes (mapa, búsqueda, contenido, filtro, ...)
Proporciona muchas funciones útiles: Contiene, Diferencia, IndexOf, LastIndexOf, etc. Para obtener más detalles, consulte su sitio web.
Pero tiene un problema fatal, es decir, utiliza la reflexión. Esto también es imposible, porque antes de que los genéricos de Go no fueran compatibles, las funciones que satisfacían diferentes tipos solo podían escribirse a través de la reflexión.
Para dar un ejemplo de IndexOf, si no necesita reflexión, si desea admitir más tipos, debe definir muchas funciones con nombres similares, como se muestra a continuación.
func IndexOfBool(a []bool, x bool) int {
}
func IndexOfInt(a []int, x int) int {
}
func IndexOfInt32(a []int32, x int32) int {
}
func IndexOfInt64(a []int64, x int64) int {
}
func IndexOfUInt(a []uint, x uint) int {
}
func IndexOfUInt32(a []uint32, x uint32) int {
}
func IndexOfUInt64(a []uint64, x uint64) int {
}
func IndexOfFloat64(a []float64, x float64) int {
}
func IndexOfString(a []string, x string) int {
}
¿Funciona la función anterior? Por supuesto, pero escribirá mucho código repetitivo y se verá raro.
Antes del soporte genérico del lenguaje Go, la única forma de solucionar este problema era a través de la reflexión.
// IndexOf gets the index at which the first occurrence of value is found in array or return -1
// if the value cannot be found
func IndexOf(in interface{}, elem interface{}) int {
inValue := reflect.ValueOf(in)
elemValue := reflect.ValueOf(elem)
inType := inValue.Type()
if inType.Kind() == reflect.String {
return strings.Index(inValue.String(), elemValue.String())
}
if inType.Kind() == reflect.Slice {
equalTo := equal(elem)
for i := 0; i < inValue.Len(); i++ {
if equalTo(reflect.Value{}, inValue.Index(i)) {
return i
}
}
}
return -1
}
El código genérico es complejo e ineficiente. . .
Entonces Go 1.18 ya admite genéricos, ¿se puede reescribir con genéricos?
La respuesta es: por supuesto que puedes, y alguien ya lo ha hecho. Esta biblioteca es https://github.com/samber/lo, y también es la protagonista que presentaremos hoy. ¡Ha sido código abierto durante 3 meses y tiene más de 6,000 estrellas! ! !
Se implementa en base a genéricos Go, sin reflexión, con alta eficiencia y código conciso. Por ejemplo, la función IndexOf ahora se implementa en esta biblioteca de la siguiente manera:
// IndexOf returns the index at which the first occurrence of a value is found in an array or return -1
// if the value cannot be found.
func IndexOf[T comparable](collection []T, element T) int {
for i, item := range collection {
if item == element {
return i
}
}
return -1
}
Siempre que T esté obligado a ser comparable, el símbolo == se puede usar para la comparación.El código general es muy simple y no hay reflexión.
IndexOf es solo una de las docenas de funciones en lo. Estas funciones básicamente cubren todos los aspectos de corte, mapa, cadena, etc., que incluyen búsqueda, comparación de tamaño, generación, mapa, reducción, filtrado, relleno, inversión, agrupación, etc. para usar Y ejemplos, puede consultar la documentación de go doc. https://pkg.go.dev/github.com/samber/lo
Asistentes admitidos para segmentos:
Filtrar
Mapa
FiltroMapa
Mapa plano
Reducir
Para cada
Veces
único
UniqPor
Agrupar por
Pedazo
partición por
aplanar
Barajar
Contrarrestar
Llenar
Repetir
clave por
Gota
soltar a la derecha
soltar mientras
SoltarDerechoMientras
Rechazar
Contar
contar por
Ayudantes admitidos para mapas:
Llaves
Valores
Recoger por
PickByKeys
PickByValues
Omitir por
Omitir por claves
Omitir por valores
Entradas
DesdeEntradas
Invertir
Asignar (fusión de mapas)
Claves del mapa
MapValues
Asistentes matemáticos admitidos:
Rango / RangoDesde / RangoConPasos
Abrazadera
suma por
Ayudantes admitidos para cadenas:
subcadena
longitud de runa
Ayudantes admitidos para tuplas:
T2 -> T9
Desempaquetar2 -> Desempaquetar9
Código postal2 -> Código postal9
Descomprimir2 -> Descomprimir9
Asistentes de intersección admitidos:
Contiene
Contiene por
Cada
cada por
Alguno
algunos por
Ninguno
NingunoPor
Intersecarse
Diferencia
Unión
Asistentes de búsqueda admitidos:
Índice de
ÚltimoÍndiceDe
Encontrar
BuscarÍndiceDe
FindLastIndexOf
mínimo
Mi ciudad
máx.
MaxPor
Último
enésimo
Muestra
Muestras
Ayudantes condicionales:
Ternario (sentencia if/else de 1 línea)
Si / De lo contrarioSi / De lo contrario
Interruptor / Caso / Predeterminado
Ayudantes de manipulación de tipos:
ToPtr
ToSlicePtr
ToAnySlice
DesdeAnySlice
Vacío
Juntarse
Asistentes de concurrencia:
Intentar
IntentoConRetraso
rebote
asíncrono
Manejo de errores:
Debe
Intentar
Trata de atraparlo
TryWithErrorValue
TryCatchWithErrorValue
Restricciones:
Clonable
Con la mejora de los genéricos del lenguaje Go, creo que estas funciones de utilidad se convertirán en parte de la biblioteca estándar de Go y serán utilizadas por más desarrolladores.
Ahora, usemos lo primero~~~~
Presentación de Go Team en GopherCon 2021: Introducción a los genéricos en Go 1.18
Una implementación simple de Golang de Socket5 Proxy
Modo de espacio de trabajo en Go 1.18
Escanear código de atención
Compartir, dar me gusta y mirar son el mayor apoyo.