Vi que o intervalo retorna a chave e a "cópia" do valor. Existe uma maneira desse intervalo retornar o endereço do item? Exemplo
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
Aqui, "campo" não é modificado porque intervalo envia a cópia do campo, Devo usar o índice ou existe alguma outra maneira de modificar o valor?
Obrigado pela leitura.
MyType
?range
está funcionando bem e retorna o que você colocou dentro da fatia. Aqui, os valores do tipoMyStruct
(que é um tipo de valor) residem dentro da fatia. Em vez disso, poderíamos colocar ponteiros do tipo*MyStruct
dentro da fatia. Se você realmente precisa que ele funcione da maneira que está, use índices em vez de valores retornados porrange
.Respostas:
A resposta curta e direta: não, use o índice da matriz em vez do valor
Portanto, o código acima se torna:
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("--") } }
fonte
array[idx]
poderá optar por tere := &array[idx]
no topo do loop for e, em seguidae.field1
, usare.field2
,, etc, que se assemelha mais ao que o OP poderia desejar (apenas com duas linhas em vez de uma)., _
inteiramente -for idx := range array
Já foi dito nos comentários, mas para aqueles que procuram respostas imediatas, veja como você pode alcançar o resultado esperado usando uma porção de ponteiros e fazendo o mínimo de alterações no código original.
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("--") } }
Aqui está no playground
fonte
e := &array[idx]
dentro de cada intervalo que tem esse ponteiro para um ponteiro ...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("--") } }
fonte