0

Example (go playgrounds)

package main

import (
    "fmt"
)

type A struct {
  B *B
}

type B struct {
  C *C
}

type C struct {
  D string
}

func main() {

  a := A{}

  // I'd like to avoid this repetitive statements
  if a.B != nil && a.B.C != nil && a.B.C.D != "" {
    fmt.Println("no nil-pointer panic here")
  }

  // I'd like to go into that if body if any of these are nil and D is not empty string
  if a.B.C.D != "" {
    fmt.Println("nil-pointer panic here")
  }

}

I can't figure out a way to check if a property is empty in a chain of pointers which should also result into false if any of them is nil. Assume these fields have a bit of a longer name - and the struct is a bit more complex - this gets unreadable pretty fast. But maybe there's no other way...

Dionysius
  • 488
  • 5
  • 10
  • if any of those are nil, `D` _can't_ be an empty string, because its memory won't be allocated. `C* C` (or an upper level) won't exist to hold `D`. – erik258 Sep 25 '19 at 13:50
  • 3
    You can't really avoid the repetitive statements. – Jonathan Hall Sep 25 '19 at 13:56
  • In my opinion an elegant way is to add getter methods that do the `nil` check, and then you can naturally chain the calls, no runtime panic will occur. This "technique" is also used in the generated Go code by protobuf. See it in [my answer of the marked duplicate](https://stackoverflow.com/a/58100426/1705598). – icza Sep 25 '19 at 14:13
  • And here's the solution to your concrete example: [Go Playground](https://play.golang.org/p/trzctjbqmDD). Basically the final code is like: `if a.B.GetC().GetD() != "" { ... }` – which does what you expect from it, and it never panics. – icza Sep 25 '19 at 14:20

0 Answers0