title: Pattern for fetching multiple fields in parallel
body: <p>I need to fetch multiple fields in parallel for my system from external services (in this example, simulated by Name(), Age() and CanDrive() methods).</p>
  
  <p>The fetchUser() method does what I want, but it seems too verbose specially if you consider I could have 10+ fields. Are there better ways I can implement this?</p>
  
  <p>playground: <a href="https://play.golang.org/p/90sNq1GmrD8" rel="nofollow noreferrer">https://play.golang.org/p/90sNq1GmrD8</a></p>
  
  <p>Code (same as in playground):</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "sync"
  )
  
  type User struct {
      Name string
      Age int
      CanDrive *bool
  }
  
  func Name() (string, error) {
      return "foobar", nil
  }
  
  func Age() (int, error) {
      return 25, nil
  }
  
  func CanDrive() (bool, error) {
      return true, nil
  }
  
  func fetchUser() (*User, error) {
      var wg sync.WaitGroup
      errs := make(chan error)
  
      user := &amp;User{}
  
      wg.Add(1)
      go func() {
          var err error
          defer wg.Done()
          user.Name, err = Name()
          errs &lt;- err
      }()
  
      wg.Add(1)
  
      go func() {
          var err error
          defer wg.Done()
          user.Age, err = Age()
          errs &lt;- err
      }()
  
      wg.Add(1)
      go func() {
          defer wg.Done()
          canDrive, err := CanDrive()
          if err == nil {
              user.CanDrive = &amp;canDrive
          }
          errs &lt;- err
      }()
  
      // wait until all go-routines are completed successfully
      // if that's the case, close the errs channel
      go func() {
          wg.Wait()
          close(errs)
      }()
  
      // keep waiting for errors (or for the error channel to be closed
      // if all calls succeed)
      for err := range errs {
          if err != nil {
              return nil, err
          }
      }
  
      return user, nil
  }
  
  func main() {
      user, _ := fetchUser()
      fmt.Println(user)
  }
  </code></pre>