title: Go equivalent of type inheritace (gob encode/decode via interfaces)
body: <p>I'm trying to write one function that encodes/decodes various types of Messages.</p>
  
  <p>In OO languages, I would use type inheritance, but Go doesn't have this concept, ref: <a href="http://golang.org/doc/faq#inheritance" rel="nofollow">http://golang.org/doc/faq#inheritance</a>, so instead, here I'm trying to use the "marker interface" style to leverage interface inheritance for this purpose instead.</p>
  
  <p>The error is from golang org src/encoding/gob/decode.go:</p>
  
  <pre><code>   line 1019// Common confusing case: local interface type, remote concrete type.
  </code></pre>
  
  <p>.. and yes I find this confusing!!</p>
  
  <p>Run this at <a href="https://play.golang.org/p/ldEvQXIgEa" rel="nofollow">https://play.golang.org/p/ldEvQXIgEa</a></p>
  
  <p>I cannot get this to work, what am I doing wrong? Help please!</p>
  
  <p>updates:</p>
  
  <p>(I also tried to gob.Register(m1) with no effect).</p>
  
  <p>I've looked into type embedding, but it doesn't do the thing that I am trying to do, as you can see in this example (that I've modified from jcbwlkr's code): https //play .golang .org/p/ P6AwVQqQcM  (also be aware that I might have dozens/hundreds of message types!)</p>
  
  <p>It is quite possible that I'm barking up the wrong tree, and that I need to ditch the whole idea of <em>how</em> I'm <em>thinking</em> about the problem (but this is what I'm trying to do at the moment: learn how to <strong>"Think in Go"</strong> vs OO thinking). Using type embedding would work, but I would then have to create a master type that embedded (composed) all of the possible types within it: gob makes the decoding possible, and a type switch lets me see what I got, but this all <em>feels</em> quite scary and uncomfortable to <em>think about</em> .</p>
  
  <p>(I am used to static and dynamic languages, so I'm happy with duck typing, but <strong>this feels like a half-way house without the comforts of either end of the spectrum</strong>!).</p>
  
  <p>So there are 2 things that I'm asking here:</p>
  
  <ol>
  <li>How to fix this particular problem (ie understand what's possible
  with interfaces), and</li>
  <li>design alternatives (and type embedding is
  one of those, so thanks for highlighting that) :) .</li>
  </ol>
  
  <p>Here;s the broken code:</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "bytes"
      "log"
      "encoding/gob"
  )
  
  type Msger interface {
      IsMsg()
  }
  
  type ClientMsg struct {
      Id      string
  }
  type ServerMsg struct {
      Id      string
  }
  
  func (m ClientMsg) IsMsg() { }
  func (m ServerMsg) IsMsg() { }
  
  func encode(m Msger) (bb bytes.Buffer) {
      enc := gob.NewEncoder(&amp;bb)
      err := enc.Encode(m)
      if err != nil {
          log.Fatal("Cannot encode! err=", err)
      }
      return
  }
  
  func decode(m Msger, bb bytes.Buffer) {     // for A
  //func decode(m *Msger, bb bytes.Buffer) {  // for B, C
      dec := gob.NewDecoder(&amp;bb)
      err := dec.Decode(&amp;m)
      if err != nil {
          log.Fatal("Cannot decode Msg! err=", err)
      }
      return
  }
  
  func main() {
      m1 := ClientMsg{"id_1"}
      b1 := encode(m1)
      p_bb := bytes.NewBuffer(b1.Bytes())
  
      var mDecoded ClientMsg // for A, B, C
      //var mDecoded interface{} // D: : cannot use mDecoded (type interface {}) as type Msger in argument to decode: interface {} does not implement Msger (missing IsMsg method)
      decode(mDecoded, *p_bb)     // A: gives: Cannot decode Msg! err=gob: local interface type *main.Msger can only be decoded from remote interface type; received concrete type ClientMsg = struct { Id string; }
  
      //decode(mDecoded, *p_bb)  // B: gives: cannot use mDecoded (type ClientMsg) as type *Msger in argument to decode: *Msger is pointer to interface, not interface
      //decode(&amp;mDecoded, *p_bb) // C: gives: cannot use &amp;mDecoded (type *ClientMsg) as type *Msger in argument to decode: *Msger is pointer to interface, not interface
  
      fmt.Printf("m1 Decoded='%v'\n", mDecoded)
  }
  </code></pre>