Go在for迴圈中修改struct slice的元素屬性的方式如下。
範例環境:
- Go 1.16
這可能是初學Golang的常見問題,for迴圈struct slice要修改每個struct元素的屬性,但發現無法修改。
例如下面在foreach(Go的for range語法)中遍歷slice emps
中的每個Employee
元素並將Age
加1,但迴圈結束後值未被修改。
main.go
package main
import "fmt"
type Employee struct {
Id int
Name string
Age int
}
func main() {
emps := []Employee{
{Id: 1, Name: "John", Age: 33},
{Id: 1, Name: "Mary", Age: 28},
}
for _, emp := range emps {
emp.Age = emp.Age + 1
}
fmt.Println(emps) // [{1 John 33} {1 Mary 28}]
}
或是用一般的for迴圈也是無法修改struct的屬性值。
package main
import "fmt"
type Employee struct {
Id int
Name string
Age int
}
func main() {
emps := []Employee{
{Id: 1, Name: "John", Age: 33},
{Id: 1, Name: "Mary", Age: 28},
}
for i := 0; i < len(emps); i++ {
emp := emps[i]
emp.Age = emp.Age + 1
}
fmt.Println(emps) // [{1 John 33} {1 Mary 28}]
}
上面的原因在於slice取出元素時是複製一份再分派到變數e
,所以原本的slice元素並沒有被修改。
因此for迴圈中slice取出元素前可加上&
取得指向該元素的指標。
main.go
package main
import "fmt"
type Employee struct {
Id int
Name string
Age int
}
func main() {
emps := []Employee{
{Id: 1, Name: "John", Age: 33},
{Id: 1, Name: "Mary", Age: 28},
}
for i := 0; i < len(emps); i++ {
emp := &emps[i] // get pointer of emps[i]
emp.Age = emp.Age + 1
}
fmt.Println(emps) // [{1 John 34} {1 Mary 29}]
}
也可修改成以下類似JavaScript forEach的味道。
main.go
package main
import (
"fmt"
)
type Employee struct {
Id int
Name string
Age int
}
func main() {
emps := []Employee{
{Id: 1, Name: "John", Age: 33},
{Id: 1, Name: "Mary", Age: 28},
}
foreach(emps, func(emp *Employee) {
emp.Age = emp.Age + 1
})
fmt.Println(emps) // [{1 John 34} {1 Mary 29}]
}
func foreach(emps []Employee, apply func(emp *Employee)) {
for i := 0; i < len(emps); i++ {
emp := &emps[i]
apply(emp)
}
}
沒有留言:
張貼留言