MessageImpl没有实现Message接口。

huangapple go评论83阅读模式
英文:

MessageImpl does not implement Message

问题

在golang中,我遇到了以下编译错误:

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

使用以下代码:

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()
}

从Java语言过来,我试图表达我的意图:
有一个接口Message定义了一些方法,由一个抽象类MessageImpl实现。两个真实的类RequestResponse应该继承自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(&quot;...&quot;)
  // Some more instructions
  return requestLine.String()
}


func (m MessageImpl) RenderMessage() string {
  var message bytes.Buffer
  var msg Message = m                   // &lt;=== 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

得分: 2

在Go语言中,接口是一组方法,但接口也是类型。因此,Go的约定是为任何接口添加后缀-er,以指示其他类型是否从中组合方法。

你需要为类型Messege定义一个实现,以实现FirstLine()方法。它作为Messeger接口的满足结果。

编辑: 我误解了你对bytes.Buffer的使用,所以答案实际上要简单得多。

编辑2: 我需要思考一下这个问题,但是看起来你希望RenderMessage()是一个函数而不是一个方法。RenderMessage有一个类型为Messeger的参数,目前可以是RequestResponseMessage类型。

如果你传递给RenderMessageMessager可以是不同类型的,你无法为RenderMessage定义方法接收器,除非你想在RenderMessage内部使用类型切换,这在某种程度上会破坏使用接口的初衷。

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))
}

输出:

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

我在你的问题中添加了以下内容:

type Header struct {
	Data string
}

我还添加了以下行来说明示例:

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

你可以在这里查看代码示例:http://play.golang.org/p/n-DOQbXXl9

英文:

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 (
&quot;bytes&quot;
&quot;fmt&quot;
)
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(&quot;...&quot;)
// Some more instructions
return requestLine.String()
}
func (r Response) FirstLine() string {
var requestLine bytes.Buffer
requestLine.WriteString(&quot;!!!&quot;)
// Some more instructions
return requestLine.String()
}
func (m Message) FirstLine() string {
// whatever this would be
return &quot;???&quot;
}
func RenderMessage(m Messager) string {
var b bytes.Buffer
var msg Messager = m // &lt;=== This is the line the compiler moans about
b.Write([]byte(&quot;some text&quot;))
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(&quot;some text&quot;))

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

huangapple
  • 本文由 发表于 2015年7月25日 00:01:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/31615005.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定