Değerler yerine aralık referansları


91

Bu aralığın anahtar ve değerin "kopyasını" döndürdüğünü gördüm. Bu aralığın öğenin adresini döndürmesinin bir yolu var mı? Misal

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

Burada "alan" değiştirilmez çünkü range, alanın kopyasını gönderir, endeksi kullanmak zorunda mıyım yoksa değeri değiştirmenin başka bir yolu var mı?

Okuduğunuz için teşekkürler.



1
Bir dizi işaretçi kullanabilir misiniz MyType?
nvcnvn

Evet, bir dizi işaretçi kullanırsanız, indeksi kullanmak zorunda kalmadan sonuçları doğrudan dizide değiştirebilirsiniz, burada bir örnek var: play.golang.org/p/_Vx7ONLDJs
notzippy

rangeiyi çalışıyor ve dilimin içine koyduğunuz şeyi geri veriyor. Burada tür değerleri MyStruct(bir değer türü olan) dilim içinde bulunur. Bunun yerine *MyStruct, dilimin içine tür işaretçileri koyabiliriz . Olduğu gibi çalışması için kesinlikle ihtiyacınız varsa, tarafından döndürülen değerler yerine dizinleri kullanabilirsiniz range.
Kaveh Shahbazian

Yanıtlar:


126

Kısa ve doğrudan cevap: hayır, değer yerine dizi dizinini kullanın

Böylece yukarıdaki kod şu hale gelir:

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
Ve tabii ki, art arda erişmek eğer array[idx]yerine sahip seçebilir e := &array[idx]döngü üstündeki ve sonra kullanmak e.field1, e.field2vb daha yakından OP (sadece bir yerine iki çizgi ile) isteyebileceğiniitiraf benzer olan.
Dave C

18
, _Tamamen bırakabilirsiniz -for idx := range array
Sam Toliman

0

Zaten yorumlarda söylendi, ancak hemen cevap arayanlar için, bir dilim işaretçi kullanarak ve orijinal kodda en az değişikliği yaparak beklenen sonucu nasıl elde edebileceğiniz aşağıda açıklanmıştır.

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

}

İşte oyun alanında


2
Gerçek şu ki, bu işaretçi yalnızca bu aralık kullanımı için kullanışlıdır. e := &array[idx]İşaretçiye bu işaretçiye sahip her aralığın içine eklemeyi tercih ederim ...
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
Bu, mevcut kabul edilmiş cevaba herhangi bir şey eklemiyor gibi görünüyor (6 yıl önce gönderilmiş).
Brits
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.