Tham chiếu phạm vi thay vì giá trị


90

Tôi thấy rằng phạm vi trả về khóa và "bản sao" của giá trị. Có cách nào để phạm vi đó trả về địa chỉ của mặt hàng không? Thí dụ

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

Ở đây "trường" không được sửa đổi vì phạm vi gửi bản sao của trường, Tôi có phải sử dụng chỉ mục hay có cách nào khác để sửa đổi giá trị không?

Cảm ơn vì đã đọc.



1
Bạn có thể sử dụng một mảng con trỏ của MyType?
nvcnvn 26/11/13

Có, nếu bạn sử dụng một mảng con trỏ, bạn có thể sửa đổi kết quả trực tiếp trong mảng mà không cần phải sử dụng chỉ mục, có một ví dụ ở đây play.golang.org/p/_Vx7ONLDJs
notzippy

rangeđang hoạt động tốt và nó trả về những gì bạn đã đặt bên trong lát. Ở đây các giá trị của kiểu MyStruct(là một kiểu giá trị) nằm bên trong lát cắt. Thay vào đó, chúng ta có thể đặt các con trỏ kiểu *MyStructbên trong lát cắt. Nếu bạn thực sự cần nó hoạt động theo cách hiện tại, bạn có thể sử dụng các chỉ mục thay vì các giá trị được trả về range.
Kaveh Shahbazian

Câu trả lời:


123

Câu trả lời ngắn gọn & trực tiếp: không, sử dụng chỉ số mảng thay vì giá trị

Vì vậy, đoạn mã trên trở thành:

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
Và tất nhiên, nếu bạn liên tục truy cập array[idx]bạn có thể thay vì chọn để e := &array[idx]ở phía trên cùng của vòng lặp for và sau đó sử dụng e.field1, e.field2, vv mà giống chặt chẽ hơn OP có thể đã muốn (chỉ với hai dòng thay vì một).
Dave C

16
Bạn có thể thả , _hoàn toàn -for idx := range array
Sam Toliman

0

Nó đã được nói trong các nhận xét rồi, nhưng đối với những người đang tìm kiếm câu trả lời ngay lập tức, đây là cách bạn có thể đạt được kết quả mong đợi bằng cách sử dụng một phần con trỏ và bằng cách thực hiện ít thay đổi nhất đối với mã gốc.

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("--")
    }

}

Đây là sân chơi


2
Thực tế là, con trỏ đó chỉ hữu ích cho việc sử dụng phạm vi này. Tôi muốn thêm e := &array[idx]vào bên trong mọi phạm vi có con trỏ đó vào một con trỏ ...
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("--")
    }
}

Điều này dường như không thêm bất cứ điều gì vào câu trả lời được chấp nhận hiện có (đã đăng 6 năm trước).
Brits
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.