Было бы удобно сказать что-то вроде:
for _, element := reverse range mySlice {
...
}
Нет, нет удобного оператора, чтобы добавить к диапазону один на месте. Вам нужно будет выполнить обычный обратный отсчет цикла:
s := []int{5, 4, 3, 2, 1}
for i := len(s)-1; i >= 0; i-- {
fmt.Println(s[i])
}
Вы также можете:
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 }
Выход:
1 2 3 4 5
Также здесь: http://play.golang.org/p/l7Z69TV7Vl
источник
Вариация с индексом
for k := range s { k = len(s) - 1 - k // now k starts from the end }
источник
Как насчет использования отсрочки:
s := []int{5, 4, 3, 2, 1} for i, _ := range s { defer fmt.Println(s[i]) }
источник
defer
но я считаю, что использовать это внутри цикла для реверса довольно сложно и должно быть довольно неэффективным с точки зрения памяти.defer
не предназначено для использования. Не используйте это, так как это может иметь неприятные побочные эффекты (выполнение вне очереди). Просто используйтеfor
цикл в принятом ответе. Go стремится свести к минимуму такие хитрые (не) хаки, поскольку они, как правило, в дальнейшем укусят вас под зад.Можно использовать канал для переворота списка в функции без его дублирования. В моем понимании это делает код лучше.
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{}
? Потому чтоreverse
функция present поддерживает только строки.func reverse(lst []interface{}) chan inyterface{}
больше не будет принимать строку [] в качестве входных данных. Даже если строка может быть преобразована в интерфейс {}, строка [] не может быть преобразована в [] интерфейс {}. К сожалению, настоящая обратная функция - это такая функция, которую нужно много переписывать.Когда мне нужно извлечь элементы из среза и обратного диапазона, я использую что-то вроде этого кода:
// 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") } }
Выход:
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}
Площадка: https://play.golang.org/p/gx6fJIfb7fo
источник