英文:
Catch nil pointer dereference in Struct properties
问题
我正在尝试找到在访问结构体属性时捕获"空指针解引用"的最佳方法。
假设我们有以下结构体(代码仅用于演示,我的意图是传达一个观点):
type Location struct {
coordinates *Coordinates
}
type Coordinates struct {
lat *Latitude
lon *Longitude
}
type Latitude struct {
lat float64
}
type Longitude struct {
lon float64
}
初始化空的Location
并访问loc.coordinates.lat
显然会产生预期的错误:
loc := Location{}
fmt.Println(loc.coordinates.lat) // 运行时错误:无效的内存地址或空指针解引用
为了解决这个问题,我可以这样做:
if loc.coordinates != nil {
fmt.Println(loc.coordinates.lat)
}
但是,在这种情况下,如果我想打印Latitude
的lat
属性,我必须添加另一个if
语句,如下所示:
if loc.coordinates != nil {
if loc.coordinates.lat != nil {
fmt.Println(loc.coordinates.lat.lat)
}
}
我想知道是否有其他处理这种情况的方法,而不必检查每个地址是否等于nil
。在Go语言中是否有类似于val, ok := someMap["foo"]
的用于结构体的方法?
英文:
I am trying to find the best way to catch nil pointer dereference
when trying to access the property of the struct that is an address to another type.
Assume we have these structs (The code is for demo only. My intention is to convey a point)
type Location struct {
coordinates *Coordinates
}
type Coordinates struct {
lat *Latitude
lon *Longitude
}
type Latitude struct {
lat float64
}
type Longitude struct {
lon float64
}
Initialising empty Location and accessing loc.coordinates.lat
obviously yields an error as expected
loc := Location{}
fmt.Println(loc.coordinates.lat) // runtime error: invalid memory address or nil pointer dereference
To solve this problem I can do
if loc.coordinates != nil {
fmt.Println(loc.coordinates.lat)
}
But in this case, if I want to print out lat
property of Latitude
I must add another if
statement as follows
if loc.coordinates != nil {
if(loc.coordinates.lat != nil){
fmt.Println(loc.coordinates.lat.lat)
}
}
I am wondering if there is any other way of handling this situation without checking if every address is not equal to nil
. Is there anything like val, ok := someMap["foo"]
in Go for structs?
答案1
得分: 2
如果你定义了指针类型,你必须处理它们可能为nil的情况。一种方法是检查每次访问。另一种方法是使用可以处理nil接收者的getter方法:
func (c *Coordinates) GetLat() (Latitude, bool) {
if c == nil {
return Latitude{}, false
}
return c.lat, true
}
func (l *Location) GetCoordinates() *Coordinates {
if l == nil {
return nil
}
return l.coordinates
}
lat, ok := l.GetCoordinates().GetLat()
if ok {
// 存在有效的纬度
}
希望对你有帮助!
英文:
If you define pointer types, you have to deal with them being possibly nil. One way to do it is to check every access. Another way is using getters that can deal with nil receivers:
func (c *Coordinates) GetLat() (Latitude,bool) {
if c==nil {
return Latitude{}, false
}
return c.lat,true
}
func (l *Location) GetCoordinates() *Coordinates {
if l==nil {
return nil
}
return l.coordinates
}
lat, ok:=l.GetCoordinates().GetLat()
if ok {
// there is a valid lat
}
答案2
得分: 2
我在想是否有其他处理这种情况的方法,而不是检查每个地址是否不等于nil。
没有,没有其他方法。(从生成的panic中恢复是一种不好的做法,容易出错且速度慢。)
在Go语言中,是否有类似于val, ok := someMap["foo"]
这样的用于结构体的方式?
没有。
英文:
> I am w[o]ndering if there is any other way of handling this situation without checking if every address is not equal to nil.
No, there isn't. (Recovering from the generated panic is a bad practice, error prone and slow.)
> Is there anything like val, ok := someMap["foo"] in Go for structs?
No.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论