Widziałem, że zakres zwraca klucz i „kopię” wartości. Czy istnieje sposób, aby ten zakres zwrócił adres przedmiotu? Przykład
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
Tutaj "pole" nie jest modyfikowane, ponieważ zakres wysyła kopię pola, czy muszę używać indeksu, czy jest inny sposób na modyfikację wartości?
Dziękuje za przeczytanie.
MyType
?range
działa dobrze i zwraca to, co umieściłeś w plasterku. Tutaj wartości typuMyStruct
(który jest typem wartości) znajdują się wewnątrz plasterka. Zamiast tego moglibyśmy umieścić wskaźniki typu*MyStruct
wewnątrz wycinka. Jeśli absolutnie potrzebujesz, aby działał tak, jak jest, możesz użyć indeksów zamiast wartości zwracanych przezrange
.Odpowiedzi:
Krótka i bezpośrednia odpowiedź: nie, użyj indeksu tablicy zamiast wartości
Tak więc powyższy kod staje się:
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("--") } }
źródło
array[idx]
można zamiast zdecydować sięe := &array[idx]
na szczycie pętli for a następnie użyće.field1
,e.field2
itp, które bardziej przypomina OP może chciał (tylko z dwóch linii zamiast jednego)., _
całkowicie zrezygnować z -for idx := range array
Zostało to już powiedziane w komentarzach, ale dla tych, którzy szukają odpowiedzi od razu, oto jak można osiągnąć oczekiwany rezultat, używając kawałka wskaźników i wprowadzając najmniej zmian w oryginalnym kodzie.
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("--") } }
Tutaj jest na placu zabaw
źródło
e := &array[idx]
wewnątrz każdego zakresu, który ma ten wskaźnik, do wskaźnika ...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("--") } }
źródło