Sẽ rất tiện lợi nếu có thể nói những điều như:
for _, element := reverse range mySlice {
...
}
Câu trả lời:
Không có toán tử nào thuận tiện cho việc này để thêm vào phạm vi một tại chỗ. Bạn sẽ phải thực hiện bình thường cho vòng lặp đếm ngược:
s := []int{5, 4, 3, 2, 1}
for i := len(s)-1; i >= 0; i-- {
fmt.Println(s[i])
}
Bạn cũng có thể làm:
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
}
Đầu ra:
1
2
3
4
5
Cũng tại đây: http://play.golang.org/p/l7Z69TV7Vl
Biến thể với chỉ mục
for k := range s {
k = len(s) - 1 - k
// now k starts from the end
}
Làm thế nào về việc trì hoãn sử dụng:
s := []int{5, 4, 3, 2, 1}
for i, _ := range s {
defer fmt.Println(s[i])
}
defer
nhưng tôi tin rằng việc sử dụng điều này bên trong một vòng lặp để đảo ngược là khá phức tạp và sẽ khá kém hiệu quả về trí nhớ.
defer
theo cách mà nó không được dự định. Không sử dụng điều này vì nó có thể có các tác dụng phụ khó chịu (thực hiện không theo thứ tự). Chỉ cần sử dụng for
vòng lặp trong câu trả lời được chấp nhận. Go nhằm mục đích giảm thiểu loại hack thông minh (không phải) này vì chúng có xu hướng cắn bạn vào mông sau này.
Người ta có thể sử dụng một kênh để đảo ngược danh sách trong một hàm mà không cần sao chép nó. Nó làm cho mã đẹp hơn theo cảm nhận của tôi.
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{}
? Bởi vì reverse
chức năng hiện tại chỉ hỗ trợ chuỗi.
func reverse(lst []interface{}) chan inyterface{}
sẽ không lấy chuỗi [] làm đầu vào nữa. Ngay cả khi chuỗi có thể được truyền trong giao diện {}, chuỗi [] không thể được truyền trong [] giao diện {}. Thật không may, hàm đảo ngược hiện tại là loại hàm cần được viết lại rất nhiều.
Khi tôi cần trích xuất các phần tử từ một lát cắt và phạm vi đảo ngược, tôi sử dụng một cái gì đó giống như mã này:
// 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")
}
}
Đầu ra:
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}
Sân chơi: https://play.golang.org/p/gx6fJIfb7fo