Golang中解决复杂结构体赋值nil map时的Panic错误
Golang中解决复杂结构体赋值nil map时的Panic错误 完整代码:https://play.golang.org/p/bctvsy7ARqS
package main
import (
"fmt"
)
type Plan struct {
BufferMeasures map[string]*ItemSiteMeasure
}
type ItemSiteMeasure struct {
itemtest string
}
func main() {
fmt.Println("start")
var buff Plan
buff.AddBuffer()
fmt.Println("end")
}
func (p *Plan) AddBuffer() {
fmt.Println("method start")
p.BufferMeasures["itmsit1"] = &ItemSiteMeasure{itemtest: "item1"}
fmt.Println("obj values : ", p.BufferMeasures)
fmt.Println("method end")
}
错误/输出:
start method start panic: assignment to entry in nil map
goroutine 1 [running]: main.(*Plan).AddBuffer(0xc000068f50) /tmp/sandbox633108119/prog.go:29 +0xe8 main.main() /tmp/sandbox633108119/prog.go:20 +0x90
更多关于Golang中解决复杂结构体赋值nil map时的Panic错误的实战教程也可以访问 https://www.itying.com/category-94-b0.html
petrus:
if p.BufferMeasures == nil { p.BufferMeasures = make(map[string]*ItemSiteMeasure) }
谢谢 Petrus,问题已解决。
更多关于Golang中解决复杂结构体赋值nil map时的Panic错误的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
要初始化一个映射,请使用内置的
make函数
package main
import (
"fmt"
)
type Plan struct {
BufferMeasures map[string]*ItemSiteMeasure
}
type ItemSiteMeasure struct {
itemtest string
}
func main() {
fmt.Println("start")
var buff Plan
buff.AddBuffer()
fmt.Println("end")
}
func (p *Plan) AddBuffer() {
if p.BufferMeasures == nil {
p.BufferMeasures = make(map[string]*ItemSiteMeasure)
}
fmt.Println("method start")
p.BufferMeasures["itmsit1"] = &ItemSiteMeasure{itemtest: "item1"}
fmt.Println("obj values : ", p.BufferMeasures)
fmt.Println("method end")
}
. start method start obj values : map[itmsit1:0xc000010230] method end end
在Golang中,当尝试向nil map赋值时会引发panic。在你的代码中,Plan结构体的BufferMeasures字段是nil map,需要先初始化才能使用。
以下是修正后的代码:
package main
import (
"fmt"
)
type Plan struct {
BufferMeasures map[string]*ItemSiteMeasure
}
type ItemSiteMeasure struct {
itemtest string
}
func main() {
fmt.Println("start")
var buff Plan
buff.AddBuffer()
fmt.Println("end")
}
func (p *Plan) AddBuffer() {
fmt.Println("method start")
// 初始化map
if p.BufferMeasures == nil {
p.BufferMeasures = make(map[string]*ItemSiteMeasure)
}
p.BufferMeasures["itmsit1"] = &ItemSiteMeasure{itemtest: "item1"}
fmt.Println("obj values : ", p.BufferMeasures)
fmt.Println("method end")
}
或者,你可以在创建Plan实例时直接初始化map:
func main() {
fmt.Println("start")
// 方法1:使用make初始化
buff := Plan{
BufferMeasures: make(map[string]*ItemSiteMeasure),
}
// 方法2:先声明后初始化
var buff2 Plan
buff2.BufferMeasures = make(map[string]*ItemSiteMeasure)
buff.AddBuffer()
fmt.Println("end")
}
还可以在结构体方法中提供更安全的初始化方式:
func (p *Plan) initBufferMeasures() {
if p.BufferMeasures == nil {
p.BufferMeasures = make(map[string]*ItemSiteMeasure)
}
}
func (p *Plan) AddBuffer() {
fmt.Println("method start")
p.initBufferMeasures()
p.BufferMeasures["itmsit1"] = &ItemSiteMeasure{itemtest: "item1"}
fmt.Println("obj values : ", p.BufferMeasures)
fmt.Println("method end")
}
关键点是:在Golang中,map是引用类型,声明后默认值为nil,必须使用make()函数或字面量初始化后才能进行赋值操作。

