dpc57092 2015-07-24 16:01
浏览 47
已采纳

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?

  • 写回答

1条回答 默认 最新

  • douwanc63652 2015-07-24 17:06
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
  • ¥50 我撰写的python爬虫爬不了 要爬的网址有反爬机制
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥120 计算机网络的新校区组网设计
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等