title: Dynamically create variables of certain type based on string in Go
body: <p><strong>Simple version</strong><br>
  How can you create a variable of a certain type based upon the value of a string?</p>
  
  <pre><code>type ta struct { a int }
  type tb struct { b float }
  type tc struct { c string }
  
  t := "tb"
  v := MagicVarFunc(t) // Returns a new allocated var of type interface{}
  v.(tb).b = 8.3
  </code></pre>
  
  <p><strong>The true example</strong><br>
  In my, surprisingly enough, working example below, I am dynamically creating variables based on a <em>string</em>. This is done by registering each struct type in a <em>map</em> with the <em>string</em> being the key and a nil-pointer of the <em>type</em> being the value.<br>
  Each <em>type</em> implements an <em>interface</em> with the method New() which returns a new variable of that specific type.</p>
  
  <p>The example below is very close to what I wish to do, where each action has a set of JSON encoded data which will populate the corresponding struct. The way I've structured it is also because I wish to be able to create new stand alone actions that I register to the map.</p>
  
  <p>I am not sure if am abusing the language now.<br>
  May anyone give me any pointers if I am completely out of my mind? Is there an obviously easier way?</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "encoding/json"
  )
  
  // All I require of an action is that it may be executed
  type ActionHandler interface {
      Exec()
      New() ActionHandler
  }
  
  // My list of actions
  var mActions = make(map[string]ActionHandler)
  
  // Action Exit (leaving the program)
  type aExit struct {}
  func (s *aExit) Exec() { fmt.Println("Good bye") }
  func (s *aExit) New() ActionHandler { return new(aExit) }
  func init() {
      var a *aExit
      mActions[`exit`] = a
  }
  
  // Action Say (say a message to someone)
  type aSay struct {
      To  string
      Msg string
  }
  func (s *aSay) Exec() { fmt.Println(`You say, "` + s.Msg + `" to ` + s.To) }
  func (s *aSay) New() ActionHandler { return new(aSay) }
  func init() {
      var a *aSay
      mActions[`say`] = a
  }
  
  func inHandler(action string, data []byte) {
      a := mActions[action].New()
      json.Unmarshal(data, &amp;a)
      a.Exec()
  }
  
  func main(){
      inHandler(`say`, []byte(`{"to":"Sonia","msg":"Please help me!"}`))
      inHandler(`exit`, []byte(`{}`))
  }
  </code></pre>