การอ้างอิงช่วงแทนค่า


91

ฉันเห็นช่วงดังกล่าวส่งคืนคีย์และ "สำเนา" ของค่า มีวิธีให้ช่วงนั้นคืนที่อยู่ของรายการหรือไม่? ตัวอย่าง

package main

import "fmt"

type MyType struct {
    field string
}

func main() {
    var array [10]MyType

    for _, e := range array {
        e.field = "foo"
    }

    for _, e := range array {
        fmt.Println(e.field)
        fmt.Println("--")
    }
}

http://play.golang.org/p/AFOGG9NGpx

ที่นี่ "ฟิลด์" ไม่ได้รับการแก้ไขเนื่องจาก range ส่งสำเนาของฟิลด์ฉันต้องใช้ดัชนีหรือมีวิธีอื่นในการแก้ไขค่าหรือไม่?

ขอบคุณที่อ่าน.



1
คุณสามารถใช้อาร์เรย์ของตัวชี้ได้MyTypeหรือไม่?
nvcnvn

ใช่ถ้าคุณใช้อาร์เรย์ของพอยน์เตอร์คุณสามารถแก้ไขผลลัพธ์ในอาร์เรย์ได้โดยตรงโดยไม่ต้องใช้ดัชนีมีตัวอย่างที่นี่play.golang.org/p/_Vx7ONLDJs
notzippy

rangeทำงานได้ดีและส่งคืนสิ่งที่คุณใส่ไว้ในชิ้นส่วน นี่คือค่าของประเภทMyStruct(ซึ่งเป็นประเภทค่า) อยู่ภายในสไลซ์ แต่เราสามารถใส่พอยน์เตอร์ประเภท*MyStructภายในชิ้นได้ หากคุณต้องการให้มันทำงานอย่างที่เป็นอยู่คุณสามารถใช้ดัชนีแทนค่าที่ส่งกลับมาrangeได้
Kaveh Shahbazian

คำตอบ:


126

คำตอบสั้น ๆ และตรง: ไม่ใช้ดัชนีอาร์เรย์แทนค่า

ดังนั้นรหัสด้านบนจึงกลายเป็น:

package main

import "fmt"

type MyType struct {
    field string
}

func main() {
    var array [10]MyType

    for idx, _ := range array {
        array[idx].field = "foo"
    }

    for _, e := range array {
        fmt.Println(e.field)
        fmt.Println("--")
    }
}

30
และแน่นอนถ้าคุณซ้ำ ๆ เข้าถึงarray[idx]คุณสามารถแทนที่จะเลือกที่จะมีe := &array[idx]ที่ด้านบนของห่วงแล้วใช้e.field1, e.field2ฯลฯ ซึ่งคล้ายกับ OP อาจมีความต้องการ (เพียงสองเส้นแทนหนึ่ง)
Dave C

18
คุณสามารถทิ้ง, _ทั้งหมด -for idx := range array
Sam Toliman

0

มีการกล่าวไว้ในความคิดเห็นแล้ว แต่สำหรับผู้ที่กำลังมองหาคำตอบทันทีนี่คือวิธีที่คุณสามารถบรรลุผลลัพธ์ที่คาดหวังโดยใช้ตัวชี้และทำการเปลี่ยนแปลงโค้ดต้นฉบับให้น้อยที่สุด

package main

import "fmt"

type MyType struct {
    field string
}

func main() {
    // Slice of pointers instead of slice of type
    var array [10]*MyType

    // Initialize array manually
    for idx := range array {
        array[idx] = &MyType{}
    }

    for _, e := range array {
        e.field = "foo"
    }

    for _, e := range array {
        fmt.Println(e.field)
        fmt.Println("--")
    }

}

ที่นี่อยู่ในสนามเด็กเล่น


2
ความจริงก็คือตัวชี้นั้นมีประโยชน์สำหรับการใช้งานในช่วงนี้เท่านั้น ฉันต้องการเพิ่มe := &array[idx]ในทุกช่วงที่มีตัวชี้นั้นเป็นตัวชี้ ...
Cirelli94

-1
package main

import "fmt"

type MyType struct {
    field string
}

func main() {
    var array [10]MyType

    for index := range array {
        array[index].field = "foo"
    }

    for _, e := range array {
        fmt.Println(e.field)
        fmt.Println("--")
    }
}

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