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?
CodePudding user response:
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
}
CodePudding user response:
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.