title: C++ Template-like behavior in Go
body: <p>For example I have two different structs <code>Foo</code> and <code>Bar</code></p>
  
  <pre><code>struct Foo {...}
  struct Bar {...}
  </code></pre>
  
  <p>and a lot of functions and other types built on them.</p>
  
  <p>C++ flavor:</p>
  
  <pre><code>template&lt;typename T&gt;
  struct Identified {
      T model;
      std::string id;
  };
  
  template&lt;typename T&gt;
  Identified&lt;T&gt; GetIdentifiedModel(std::string id) {
      Identified&lt;T&gt; result;
      T.id = id;
      T.model.set(getSomeData(id));  // Common method for T
      return result;
  }
  </code></pre>
  
  <p>How to implement these examples in Go?</p>
  
  <p>For common methods, interfaces do the job but I don't see how to retrieve a specific type from an interface to declare it, return it or anything else and I can't handle copy/paste code anymore :)</p>
  
  <p>Thanks !</p>
  
  <p>Edit @Amd: <a href="https://ideone.com/rqpsQb" rel="nofollow">https://ideone.com/rqpsQb</a></p>
  
  <pre><code>#include &lt;string&gt;
  #include &lt;iostream&gt;
  
  struct Foo {
      char c;
      void set(std::string s) {c = s[0];}; // We don't really care here
  };
  struct Bar {
      int n;
      void set(std::string s) {n = s.size();}; // We don't really care here
  };
  
  template&lt;typename T&gt;
  struct Identified {
      T model;
      std::string id;
  };
  
  template&lt;typename T&gt;
  Identified&lt;T&gt; GetIdentifiedModel(std::string id) {
      Identified&lt;T&gt; result;
      result.id = id;
      // Obviously shouldn't be ID but for the example
      result.model.set(id);  // Common method for T
      return result;
  }
  
  void assert(bool b) {
      if (b) std::cout &lt;&lt; "OK" &lt;&lt; std::endl;
      else std::cout &lt;&lt; "There is a problem !" &lt;&lt; std::endl;
  };
  
  int main() {
      auto fooWithID = GetIdentifiedModel&lt;Foo&gt;("foo id");
      auto barWithID = GetIdentifiedModel&lt;Bar&gt;("bar");
      assert (fooWithID.model.c == 'f');
      assert (barWithID.model.n == 3);
      return (0);
  }
  </code></pre>