El rango de Go puede iterar sobre mapas y sectores, pero me preguntaba si hay una manera de iterar sobre un rango de números, algo como esto:
for i := range [1..10] {
fmt.Println(i)
}
¿O hay una manera de representar el rango de enteros en Go como lo hace Ruby con la clase Range ?
Aquí hay un programa para comparar las dos formas sugeridas hasta ahora
Compila de esta manera para generar el desmontaje
Aquí está claro (he eliminado las no instrucciones de la lista)
preparar
lazo
Y aquí está con_iter
preparar
lazo
Entonces puede ver que la solución iter es considerablemente más costosa a pesar de que está totalmente integrada en la fase de configuración. En la fase de bucle hay una instrucción adicional en el bucle, pero no es tan malo.
Yo usaría el simple for loop.
fuente
runtime.makeslice
y la otra no. ¡No necesito un punto de referencia para saber que va a ser mucho más lento!runtime.makeslice
es lo suficientemente inteligente como para no asignar memoria si solicita una asignación de tamaño cero. Sin embargo, lo anterior todavía lo llama, y de acuerdo con su punto de referencia, toma 10nS más en mi máquina.Mark Mishyn le sugirió que usara el segmento, pero no hay ninguna razón para crear una matriz
make
y usarla en lafor
sección devuelta cuando la matriz creada a través del literal se puede usar y es más cortafuente
for range [5]int{} {
5
aquí hay un literal y no se puede determinar en tiempo de ejecución.iter es un paquete muy pequeño que solo proporciona una forma sintácticamente diferente de iterar sobre enteros.
Rob Pike (autor de Go) lo ha criticado :
fuente
iter
versión realmente utiliza menos pulsaciones debidorange
yiter
autocompletará.for
bucles no son ciudadanos de primera clase de Unix como están en marcha. Además, a diferencia defor
,seq
arroyos en la salida estándar una secuencia de números. Si se debe iterar sobre ellos o no, depende del consumidor. Aunquefor i in $(seq 1 10); do ... done
es común en Shell, es solo una forma de hacer un bucle for, que en sí mismo es solo una forma de consumir la salidaseq
, aunque es muy común.i in range(10)
exactamente iguali := 0; i < 10; i++
.Aquí hay un punto de referencia para comparar una
for
declaración Go con una ForClause y unarange
declaración Go usando eliter
paquete.iter_test.go
Salida:
fuente
Si bien me compadezco de su preocupación por la falta de esta función de lenguaje, probablemente solo quiera usar un
for
bucle normal . Y probablemente estará más de acuerdo con eso de lo que piensa al escribir más código Go.Escribí este paquete iter , que está respaldado por un
for
bucle simple e idiomático que devuelve valores sobre unchan int
, en un intento de mejorar el diseño que se encuentra en https://github.com/bradfitz/iter , que se ha señalado que tiene problemas de caché y rendimiento, así como una implementación inteligente, pero extraña y poco intuitiva. Mi propia versión funciona de la misma manera:Sin embargo, la evaluación comparativa reveló que el uso de un canal era una opción muy costosa. La comparación de los 3 métodos, que se pueden ejecutar desde
iter_test.go
mi paquete usandocuantifica cuán pobre es su rendimiento
En el proceso, este punto de referencia también muestra cómo la
bradfitz
solución tiene un rendimiento inferior en comparación con lafor
cláusula incorporada para un tamaño de bucle de10
.En resumen, parece que hasta ahora no se ha descubierto una forma de duplicar el rendimiento de la
for
cláusula incorporada al tiempo que proporciona una sintaxis simple[0,n)
como la que se encuentra en Python y Ruby.Lo cual es una pena porque probablemente sería fácil para el equipo de Go agregar una regla simple al compilador para cambiar una línea como
al mismo código de máquina que
for i := 0; i < 10; i++
.Sin embargo, para ser justos, después de escribir el mío
iter.N
(pero antes de compararlo), revisé un programa recientemente escrito para ver todos los lugares donde podría usarlo. En realidad no había muchos. Solo había un lugar, en una sección no vital de mi código, donde podía pasar sin lafor
cláusula predeterminada más completa .Entonces, aunque parezca que esto es una gran decepción para el lenguaje en principio, puede encontrar, como lo hice yo, que en realidad no lo necesita en la práctica. Como se sabe que Rob Pike dice para los genéricos, es posible que no se pierda esta característica tanto como cree que lo hará.
fuente
Si desea simplemente iterar sobre un rango sin usar e índices o cualquier otra cosa, esta muestra de código funcionó bien para mí. No se necesita declaración adicional, no
_
. Sin embargo, no he verificado el rendimiento.PD: El primer día en GoLang. Por favor, critique si es un enfoque equivocado.
fuente
non-constant array bound
de mí.También puedes visitar github.com/wushilin/stream
Es un flujo lento como el concepto de java.util.stream.
Espero que esto ayude
fuente
fuente
He escrito un paquete en Golang que imita la función de rango de Python:
Paquete https://github.com/thedevsaddam/iter
fuente