MessageImpl不实现Message

In golang, I'm having the following compile error:

cannot use m (type MessageImpl) as type Message in assignment:
    MessageImpl does not implement Message (missing FirstLine method)

Using the following code:

type Message interface {
  FirstLine() string
  /* some other method declarations*/
}

type MessageImpl struct {
  headers     []Header
  /* some other fields */
}

type Request struct {
  MessageImpl
  /* some other fields */
}

type Response struct {
  MessageImpl
  /* some other fields */
}

func (r Request) FirstLine() string {
  var requestLine bytes.Buffer
  requestLine.WriteString("...")
  // Some more instructions
  return requestLine.String()
}


func (m MessageImpl) RenderMessage() string {
  var message bytes.Buffer
  var msg Message = m                   // <=== This is the line the compiler moans about
  message.WriteString(msg.FirstLine())
  // Some more instructions
  return message.String()
}

Coming from java language, I'll try to express my intention: Having some interface Message defining some methods implemented by an abstract class MessageImpl. Two real classes Request and Response should inherit from MessageImpl (and implement the interface Message). Both of these define and implement some more internal methods.

How is this done best?

An interface in go is a set of methods, but interfaces are also types. So the go convention is to suffix -er for any interface to indicate whether or not other types compose methods from it.

You need to define an implementation for the type Messege to receive the FirstLine() method. It satisfies the Messeger interface as a result.

Edit: I misunderstood what you were doing with bytes.Buffer, so the answer is actually a lot simpler.

Edit2: I had to think about this one a bit but it seems you want RenderMessage() to be a function instead of a method. RenderMessage has a parameter of type Messeger which can (so far) either be of type Request, Response, or Message.

You can't define a method receiver for RenderMessage if the Messager you're passing can be of variable type, unless you want to have a type switch within RenderMessage, which somewhat defeats the purpose of using an interface to begin with.

package main

import (
    "bytes"
    "fmt"
)

type Messager interface {
    FirstLine() string
    /* some other method declarations*/
}

type Header struct {
    Data string
}

type Message struct {
    headers []Header
    /* some other fields */
}

type Request struct {
    /* some fields */
    Message
}

type Response struct {
    /* some fields */
    Message
}

func (r Request) FirstLine() string {
    var requestLine bytes.Buffer
    requestLine.WriteString("...")
    // Some more instructions
    return requestLine.String()
}

func (r Response) FirstLine() string {
    var requestLine bytes.Buffer
    requestLine.WriteString("!!!")
    // Some more instructions
    return requestLine.String()
}

func (m Message) FirstLine() string {
    // whatever this would be
    return "???"
}

func RenderMessage(m Messager) string {
    var b bytes.Buffer
    var msg Messager = m // <=== This is the line the compiler moans about
    b.Write([]byte("some text"))
    b.WriteString(msg.FirstLine())
    // Some more instructions
    return b.String()
}

func main() {
    header := Request{}
    fmt.Println(RenderMessage(header))

    resp := Response{}
    fmt.Println(RenderMessage(resp))

    foo := Message{}
    fmt.Println(RenderMessage(foo))
}

Output:

some text...
some text!!!
some text???

I added this since it wasn't defined in your question:

type Header struct {
    Data string
}

I also added this line to illustrate the example:

    b.Write([]byte("some text"))

http://play.golang.org/p/n-DOQbXXl9