title: Decoding arguments using reflection
body: <p>This is a followup question to <a href="https://stackoverflow.com/questions/47625370/function-and-argument-unmarshalling-in-go">Function and argument unmarshalling in go?</a>.  </p>
  
  <p>Given the following interface variable.</p>
  
  <pre><code>var args interface{}
  </code></pre>
  
  <p>Assuming as an example it contained these bytes:</p>
  
  <pre><code>[[74 111 104 110] [32 97 110 100 32 74 97 110 101]]
  </code></pre>
  
  <p>i.e. two strings "John", " and Jane"</p>
  
  <p>And a function value obtained by MethodByName</p>
  
  <pre><code>f := reflect.ValueOf(s.functions).MethodByName("Hello")
  if f.IsValid() {
    val := reflect.ValueOf(args)
    //  Do some kind of conversion...
  
    result := f.Call(val) // This won't compile. Wrong type.  How do I massage args of type interface{} into what's expected by the call.
  
  }
  </code></pre>
  
  <p>I don't particularly care if it fails. I will capture the failure of the call with recover.</p>
  
  <p>Here is a bit more detail:</p>
  
  <pre><code>var req struct {
      Ver      int
      MsgID    int
      FuncName string
      Args     interface{}
  }
  
  dec := codec.NewDecoder(frame, s.h)
  
  err = dec.Decode(&amp;req)
  if err != nil {
      s.log.Println(err)
      break
  }
  
  fmt.Println("New Msg:")
  fmt.Printf(" ver  : %d\n", req.Ver)
  fmt.Printf(" id   : %d\n", req.MsgID)
  fmt.Printf(" func : %s\n", req.FuncName)
  
  f := reflect.ValueOf(s.functions).MethodByName(req.FuncName)
  if f.IsValid() {
      defer func() {
          if r := recover(); r != nil {
              fmt.Println("Recovered in f", r)
          }
      }()
  
      fmt.Println("Function is: ", req.FuncName)
      var callArgs []reflect.Value
      args := reflect.ValueOf(req.Args)
      t := f.Type()
      for i := 0; i &lt; t.NumIn(); i++ {
          t := t.In(i)
          v := reflect.New(t).Elem()
          if i &lt; args.Len() {
              // Convert arg to type of v and set.
              arg := args.Index(i)
              switch t.Kind() {
              case reflect.String:
                  v.SetString(string(reflect.Value.Bytes(arg)))
              case reflect.Slice:
                  if t.Elem() == reflect.TypeOf(byte(0)) {
                      v.SetBytes(reflect.Value.Bytes(arg))
                  } else {
                      panic("not supported")
                  }
              case reflect.Int:
                  //i, err := strconv.ParseInt(string(arg), 10, 0)
                  // if err != nil {
                  //  panic("bad int")
                  // }
                  // v.SetInt(i)
              default:
                  panic("not supported")
              }
          }
          // Collect arguments for the call below.
          callArgs = append(callArgs, v)
      }
      result := f.Call(callArgs)
      fmt.Println(result)
  
      val := reflect.ValueOf(req.Args)
      a := []reflect.Value{val}
  
      r := f.Call(a)
      fmt.Println("Returned", r[0], r[1])
  }
  </code></pre>
  
  <p>Outputs:</p>
  
  <p>New Msg:
   ver  : 2
   id   : 1
   func : Hello
  Function is:  Hello
  Recovered in f reflect: call of reflect.Value.Bytes on interface Value</p>
  
  <p>Note:  This is an RPC API.  I have a function name (see link at top of question) and some arguments that are passed in as an array.  The arguments in my example here are strings but could anything that you could pass to a function.  It's whatever the function requires.  It's generic.</p>
  
  <p>e.g. </p>
  
  <p>Hello(name ...string) string</p>
  
  <p>or</p>
  
  <p>Add(n ...int) int</p>
  
  <p>or </p>
  
  <p>DoSomething(a string, b int, c bool)</p>
  
  <p>etc</p>
  
  <p>i.e.  I'm unmarshalling the arguments and I don't know what they are.
  Except that I do know they will be passed into a slice and
  thrown into a variable Args which has the type <code>interface{}</code>  I hope this makes sense now</p>