มีวิธีทำซ้ำในส่วนที่กลับด้านใน Go หรือไม่?


คำตอบ:


146

ไม่มีตัวดำเนินการที่สะดวกสำหรับสิ่งนี้ที่จะเพิ่มลงในช่วงหนึ่งในสถานที่ คุณจะต้องทำแบบปกติสำหรับการนับถอยหลังแบบวนซ้ำ:

s := []int{5, 4, 3, 2, 1}
for i := len(s)-1; i >= 0; i-- {
   fmt.Println(s[i])
}

การเดินทางที่มีประสิทธิภาพหน้าตัวอย่าง แต่คนนี้เป็นจริงดีกว่าเล็กน้อยและประกาศตัวแปรน้อยลง
Kevin Cantwell

3
IMO Go ต้องการการสร้างช่วงจากมากไปหาน้อย การไม่มีมันทำให้เกิดงานพิเศษขึ้นอย่างที่เห็น .... -
เวกเตอร์

24
ฉันจะไม่พูดอย่างสิ้นหวังมันคงจะดีไม่น้อย
Adam Kurkiewicz



6

วิธีใช้ defer:

s := []int{5, 4, 3, 2, 1}
for i, _ := range s {
   defer fmt.Println(s[i])
}

9
ฉันได้รับการโหวตเพียงเพราะมันนำความรู้ใหม่ ๆ มาให้deferแต่ฉันเชื่อว่าการใช้สิ่งนี้ภายในลูปสำหรับการย้อนกลับนั้นค่อนข้างยุ่งยากและควรใช้ความจำที่ไม่ได้ผล
Alexander Trakhimenok

11
มัน "ทำงาน" แต่ถ้าการวนซ้ำไม่ใช่สิ่งสุดท้ายในฟังก์ชันคุณอาจได้รับผลลัพธ์ที่ไม่คาดคิด ตัวอย่าง.
Daniel

6
นี่เป็นการใช้งานdeferในลักษณะที่ไม่ได้มีไว้สำหรับ อย่าใช้สิ่งนี้เนื่องจากอาจมีผลข้างเคียงที่น่ารังเกียจ (ไม่อยู่ในการดำเนินการตามคำสั่ง) เพียงใช้forลูปในคำตอบที่ยอมรับ Go มีเป้าหมายที่จะลดการแฮ็ก (ไม่) ฉลาดประเภทนี้ให้น้อยที่สุดเนื่องจากพวกเขามักจะกัดคุณในภายหลัง
RickyA

6
นี่เป็นการใช้การเลื่อนเวลาอย่างแฮกเกอร์และควรหลีกเลี่ยง ตัวอย่างเช่นหากเป็นฟังก์ชันที่ใครบางคนอาจขยายออกไปในอนาคตอาจมีผลที่ไม่คาดคิด
Amir Keibi

6
นี่ยังไม่ 'iffy' เพียงพอดังนั้นฉันจึงไปข้างหน้าและเพิ่มช่องplay.golang.org/p/GodEiv1LlIJ
Xeoncross

4

หนึ่งสามารถใช้ช่องเพื่อย้อนกลับรายการในฟังก์ชันโดยไม่ต้องทำซ้ำ มันทำให้รหัสดีขึ้นในความหมายของฉัน

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ฟังก์ชันปัจจุบันรองรับเฉพาะสตริง
Atmocreations

แน่นอนเพียงแค่แทนที่สตริงด้วยอินเทอร์เฟซ {} และคุณก็พร้อมที่จะไป ฉันแค่ต้องการเน้นว่าฟังก์ชันที่มีลายเซ็นfunc reverse(lst []interface{}) chan inyterface{} จะไม่ใช้สตริง [] เป็นอินพุตอีกต่อไป แม้ว่าจะสามารถแคสต์สตริงในอินเทอร์เฟซ {} ได้ แต่ [] ก็ไม่สามารถแคสต์ใน [] อินเทอร์เฟซ {} ได้ น่าเสียดายที่ฟังก์ชันย้อนกลับปัจจุบันเป็นฟังก์ชันที่ต้องเขียนใหม่เป็นจำนวนมาก
user983716

ขอบคุณ. นั่นเป็นส่วนที่น่าเกลียดของฉันซึ่งเป็นสิ่งที่หลีกเลี่ยงไม่ได้ ขอบคุณ!
Atmocreations

ฉันจะใช้สแต็กมากกว่าสิ่งนี้
ᐅ devrimbaris

0

เมื่อฉันต้องการแยกองค์ประกอบจากชิ้นส่วนและช่วงย้อนกลับฉันใช้รหัสนี้:

// 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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.