
在 Go 中使用构造函数初始化结构体成员
初始化结构体成员可能具有挑战性,尤其是对于初学者而言。让我们深入研究一个问题,即创建一个新的结构体实例(“sm”)并在其上调用函数(“sm.Put”)会因 nil 指针而导致恐慌。
问题:
1 2 3 4 | <br>导入“同步”</p>
<p>类型SyncMap struct {</p>
<div class = "code" style= "position:relative; padding:0px; margin:0px;" ><pre class = "brush:php;toolbar:false" > lock *sync.RWMutex
hm map[string]string
|
登录后复制
}
func (m *SyncMap) Put (k, v string) {
1 2 3 4 | m.lock.Lock()
defer m.lock.Unlock()
m.hm[k] = v, true
|
登录后复制
}
func main() {
1 2 | sm := new (SyncMap)
sm.Put( "Test, " Test")
|
登录后复制
}
此代码失败,因为 lock 和 hm 字段都未初始化。
解决方法(不是理想):
一种解决方法是添加 Init 函数并手动创建实例后初始化字段:
1 2 | <br>func (m *SyncMap) Init() {<pre class = "brush:php;toolbar:false" > m.hm = make(map[string]string)
m.lock = new (sync.RWMutex)
|
登录后复制
}
优雅的解决方案:使用构造函数
更好的方法是使用构造函数来初始化结构体:
1 | <br>func NewSyncMap() *SyncMap {<pre class = "brush:php;toolbar:false" > return &SyncMap{hm: make(map[string]string)}
|
登录后复制
}
作者调用 NewSyncMap(),可以创建一个带有初始化成员的新实例。
高级构造函数:
对于更复杂的结构体,构造函数可以执行其他初始化任务,例如启动 goroutine 或注册终结器:
1 2 3 4 5 6 7 8 9 10 | <br>func NewSyncMap() *SyncMap {<pre class = "brush:php;toolbar:false" >sm := SyncMap{
hm: make(map[string]string),
foo: "Bar" ,
}
runtime.SetFinalizer(sm, (*SyncMap).stop)
go sm.backend()
return &sm
|
登录后复制
}
结论:
构造函数提供了一个优雅且灵活的初始化结构体成员的方法。通过利用它们,您可以简化新结构实例的创建,消除零指针恐慌,并简化复杂数据结构的初始化过程。
以上是构造函数如何解决初始化 Go 结构体时出现的 Nil 指针恐慌?的详细内容。更多信息请关注PHP中文网其他相关文章!