Ce serait pratique de pouvoir dire quelque chose comme:
for _, element := reverse range mySlice {
...
}
Réponses:
Non, il n'y a pas d'opérateur pratique à ajouter à la plage en place. Vous devrez faire un compte à rebours normal pour la boucle:
s := []int{5, 4, 3, 2, 1}
for i := len(s)-1; i >= 0; i-- {
fmt.Println(s[i])
}
Vous pouvez également faire:
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
}
Production:
1
2
3
4
5
Aussi ici: http://play.golang.org/p/l7Z69TV7Vl
Variation avec index
for k := range s {
k = len(s) - 1 - k
// now k starts from the end
}
Que diriez-vous d'utiliser différer:
s := []int{5, 4, 3, 2, 1}
for i, _ := range s {
defer fmt.Println(s[i])
}
defer
mais je pense que l'utiliser dans une boucle pour inverser est assez délicat et devrait être assez inefficace en termes de mémoire.
defer
d'une manière pour laquelle il n'est pas prévu. Ne l'utilisez pas car cela peut avoir des effets secondaires désagréables (exécution dans le désordre). Utilisez simplement la for
boucle dans la réponse acceptée. Go vise à minimiser ce genre de hacks intelligents (pas) car ils ont tendance à vous mordre le cul plus tard.
On pourrait utiliser un canal pour inverser une liste dans une fonction sans la dupliquer. Cela rend le code plus agréable à mon sens.
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{}
? Parce que la fonction actuelle reverse
ne prend en charge que les chaînes.
func reverse(lst []interface{}) chan inyterface{}
ne prendra plus une chaîne [] comme entrée. Même si la chaîne peut être castée dans l'interface {}, la chaîne [] ne peut pas être castée dans [] interface {}. Malheureusement, la fonction inverse actuelle est le genre de fonction qui a beaucoup besoin d'être réécrite.
Lorsque j'ai besoin d'extraire des éléments d'une tranche et d'une plage inversée, j'utilise quelque chose comme ce code:
// 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")
}
}
Production:
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}
Aire de jeu: https://play.golang.org/p/gx6fJIfb7fo