title: Pass slice as function argument, and modify the original slice
body: <p>I know everything is passed by value in Go, meaning if I give a slice to a function and that function appends to the slice using the builtin <code>append</code> function, then the original slice will not have the values that were appended in the scope of the function.</p>
  
  <p>For instance:</p>
  
  <pre><code>nums := []int{1, 2, 3}
  
  func addToNumbs(nums []int) []int {
      nums = append(nums, 4)
      fmt.Println(nums) // []int{1, 2, 3, 4}
  }
  
  fmt.Println(nums) // []int{1, 2, 3}
  </code></pre>
  
  <p>This causes a problem for me, because I am trying to do recursion on an accumulated slice, basically a <code>reduce</code> type function except the reducer calls itself.</p>
  
  <p>Here is an example:</p>
  
  <pre><code>func Validate(obj Validatable) ([]ValidationMessage, error) {
      messages := make([]ValidationMessage, 0)
  
      if err := validate(obj, messages); err != nil {
          return messages, err
      }
  
      return messages, nil
  }
  
  func validate(obj Validatable, accumulator []ValidationMessage) error {
      // If something is true, recurse
      if something {
          if err := validate(obj, accumulator); err != nil {
              return err
          }
      }
  
      // Append to the accumulator passed in
      accumulator = append(accumulator, message)
  
      return nil
  }
  </code></pre>
  
  <p>The code above gives me the same error as the first example, in that the <code>accumulator</code> does not get all the appended values because they only exist within the scope of the function.</p>
  
  <p>To solve this, I pass in a pointer struct into the function, and that struct contains the accumulator. That solution works nicely.</p>
  
  <p>My question is, is there a better way to do this, and is my approach idiomatic to Go?</p>
  
  <p><strong>Updated solution</strong> (thanks to icza):</p>
  
  <p>I just return the slice in the recursed function. Such a facepalm, should have thought of that.</p>
  
  <pre><code>func Validate(obj Validatable) ([]ValidationMessage, error) {
      messages := make([]ValidationMessage, 0)
      return validate(obj, messages)
  }
  
  func validate(obj Validatable, messages []ValidationMessage) ([]ValidationMessage, error) {
      err := v.Struct(obj)
  
      if _, ok := err.(*validator.InvalidValidationError); ok {
          return []ValidationMessage{}, errors.New(err.Error())
      }
  
      if _, ok := err.(validator.ValidationErrors); ok {
          messageMap := obj.Validate()
  
          for _, err := range err.(validator.ValidationErrors) {
              f := err.StructField()
              t := err.Tag()
  
              if v, ok := err.Value().(Validatable); ok {
                  return validate(v, messages)
              } else if _, ok := messageMap[f]; ok {
                  if _, ok := messageMap[f][t]; ok {
                      messages = append(messages, ValidationMessage(messageMap[f][t]))
                  }
              }
          }
      }
  
      return messages, nil
  }
  </code></pre>