在 Go 语言中,map 的值类型是按值传递的,因此当访问 map 中的结构体时,返回的是结构体的副本,无法直接修改原始结构体的字段。为了在不进行拷贝的情况下访问和修改 map 中的结构体字段,我们可以采用以下两种方式:
- 使用指针。将 map 的值类型改为指向结构体的指针,这样就可以通过指针直接修改结构体字段。
- 避免直接修改 map 中的值:如果使用值类型,需要在修改时显式地将值取出、修改后再重新赋值回 map。
type Computer struct {
CPU int
ROM int
Disk int
}
func main() {
computers := map[string]Computer{
"PC1": {CPU: 4, ROM: 8, Disk: 256},
}
// 不能直接修改 map 中的结构体字段
computers["PC1"].CPU = 8
// 获取结构体的副本
pc1 := computers["PC1"]
// 修改结构体副本的字段,不影响原 map 中的值
pc1.CPU = 8
}
为了避免值拷贝的问题,可以将 map 的值类型改为结构体的指针,这样通过键访问 map 时,返回的是结构体的指针,对指针的修改将直接作用于原始的结构体。
type Computer struct {
CPU int
ROM int
Disk int
}
func main() {
// 创建一个 map,其值为指向结构体的指针
computers := map[string]*Computer{
"PC1": {CPU: 4, ROM: 8, Disk: 256},
"PC2": {CPU: 4, ROM: 8, Disk: 256},
}
// 通过指针直接修改结构体字段
computers["PC1"].CPU = 8
// 遍历 map 并修改结构体字段
for key, computer := range computers {
computer.CPU++
}
}
也可以取出值,修改后再放回去。
type Computer struct {
CPU int
ROM int
Disk int
}
func main() {
computers := make(map[string]Computer )
computers ["PC1"] = Computer{CPU: 4, ROM: 8, Disk: 256}
// 显式取出、修改、再赋回 map
computer := computers["PC1"]
computer.CPU = 8
computers["PC1"] = computer
}