Sería conveniente poder decir algo como:
for _, element := reverse range mySlice {
...
}
Respuestas:
No, no hay un operador conveniente para agregarlo al rango existente. Tendrá que hacer una cuenta regresiva normal de bucle for:
s := []int{5, 4, 3, 2, 1}
for i := len(s)-1; i >= 0; i-- {
fmt.Println(s[i])
}
También puedes hacer:
s := []int{5, 4, 3, 2, 1}
for i := range s {
fmt.Println(s[len(s)-1-i]) // Suggestion: do `last := len(s)-1` before the loop
}
Salida:
1
2
3
4
5
También aquí: http://play.golang.org/p/l7Z69TV7Vl
Variación con índice
for k := range s {
k = len(s) - 1 - k
// now k starts from the end
}
¿Qué tal el uso diferido?
s := []int{5, 4, 3, 2, 1}
for i, _ := range s {
defer fmt.Println(s[i])
}
defer
pero creo que usar esto dentro de un bucle para revertir es bastante complicado y debería ser bastante ineficaz en cuanto a la memoria.
defer
de una manera para la que no está diseñado. No use esto ya que puede tener efectos secundarios desagradables (ejecución fuera de orden). Simplemente use el for
bucle en la respuesta aceptada. Go tiene como objetivo minimizar este tipo de (no) trucos inteligentes , ya que tienden a morderte el culo más adelante.
Se podría usar un canal para invertir una lista en una función sin duplicarla. Hace que el código sea más agradable en mi sentido.
package main
import (
"fmt"
)
func reverse(lst []string) chan string {
ret := make(chan string)
go func() {
for i, _ := range lst {
ret <- lst[len(lst)-1-i]
}
close(ret)
}()
return ret
}
func main() {
elms := []string{"a", "b", "c", "d"}
for e := range reverse(elms) {
fmt.Println(e)
}
}
[]interface{}
? Porque la función presente reverse
solo admite cadenas.
func reverse(lst []interface{}) chan inyterface{}
ya no tomará una cadena [] como entrada. Incluso si la cadena se puede convertir en la interfaz {}, [] la cadena no se puede convertir en la [] interfaz {}. Desafortunadamente, la función inversa actual es el tipo de función que debe reescribirse mucho.
Cuando necesito extraer elementos de un segmento y rango inverso, uso algo como este código:
// reverse range
// Go Playground: https://play.golang.org/p/gx6fJIfb7fo
package main
import (
"fmt"
)
type Elem struct {
Id int64
Name string
}
type Elems []Elem
func main() {
mySlice := Elems{{Id: 0, Name: "Alice"}, {Id: 1, Name: "Bob"}, {Id: 2, Name: "Carol"}}
for i, element := range mySlice {
fmt.Printf("Normal range: [%v] %+v\n", i, element)
}
//mySlice = Elems{}
//mySlice = Elems{{Id: 0, Name: "Alice"}}
if last := len(mySlice) - 1; last >= 0 {
for i, element := last, mySlice[0]; i >= 0; i-- {
element = mySlice[i]
fmt.Printf("Reverse range: [%v] %+v\n", i, element)
}
} else {
fmt.Println("mySlice empty")
}
}
Salida:
Normal range: [0] {Id:0 Name:Alice}
Normal range: [1] {Id:1 Name:Bob}
Normal range: [2] {Id:2 Name:Carol}
Reverse range: [2] {Id:2 Name:Carol}
Reverse range: [1] {Id:1 Name:Bob}
Reverse range: [0] {Id:0 Name:Alice}
Zona de juegos: https://play.golang.org/p/gx6fJIfb7fo