Go接口:net.Conn不是io.ReadWriteCloser吗?

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

Go interfaces: is not net.Conn a io.ReadWriteCloser?

问题

我对Go语言中接口的用途有一个问题。我还在学习这门语言,所以如果问题很愚蠢,请原谅。

我正在尝试编写一个小应用程序来接受和处理TCP连接。因为我想测试业务逻辑而不是网络操作,所以我试图使用接口来保持一定的抽象性(这样我就可以使用简单的io.ReadWriteCloser对象来模拟net.Conn对象)。

这是我的问题:

type Accepter interface {
	Accept() (io.ReadWriteCloser, error)
}

func NewTCPAccepter(address string) (Accepter, error) {
	accepter, err := net.Listen("tcp", address)
	if err != nil {
		return nil, err
	}
	return accepter, err
}

我看到的错误是:

net.Listener does not implement Accepter (wrong type for Accept method)
                have Accept() (net.Conn, error)
                want Accept() (io.ReadWriteCloser, error)

我不明白为什么会出现这个错误,因为根据文档和net库的源代码,我看到net.Conn实际上是实现了io.ReadWriteCloser接口的。

我犯了什么错误?非常感谢!

英文:

I have a question about the uses of interfaces in go. I am still learning the language, so please forgive me if it is a stupid question.

I am playing with a little application that accept and handle TCP connections. Because I want to test the business logic and not the network magic, I am trying to keep it a little bit abstract using interfaces (so I can simulate net.Conn object using simple io.ReadWriteCloser objects).

Here is my problem:

type Accepter interface {
	Accept() (io.ReadWriteCloser, error)
}

func NewTCPAccepter(address string) (Accepter, error) {
	accepter, err := net.Listen("tcp", address)
	if err != nil {
		return nil, err
	}
	return accepter, err
}

The error I see is:

net.Listener does not implement Accepter (wrong type for Accept method)
                have Accept() (net.Conn, error)
                want Accept() (io.ReadWriteCloser, error)

What I do not understand is why this is happening, because checking the documentation and the net lib source code, I see that net.Conn is actually implementing io.ReadWriteCloser.

What is my mistake? Thanks a lot!

答案1

得分: 1

错误告诉你问题所在:

net.Listener没有实现Accepter(Accept方法的类型错误)
                有 Accept() (net.Conn, error)
                需要 Accept() (io.ReadWriteCloser, error)

你的返回类型与接口定义的不同。仔细看一下错误信息中的havewant语句。

英文:

The error is telling you exactly what the issue is:

net.Listener does not implement Accepter (wrong type for Accept method)
                have Accept() (net.Conn, error)
                want Accept() (io.ReadWriteCloser, error)

You have a different return time than what your interface has defined. Take a second look at the error message have and want statement.

答案2

得分: 1

我不相信存在愚蠢的问题。如果有一个诚实的问题,那就有了对知识的渴望,根据定义,它就不会是愚蠢的 Go接口:net.Conn不是io.ReadWriteCloser吗?

Go语言依赖于方法签名来判断两个接口是否相同。如果两个方法签名返回的类型本质上不同,那么你不能说这两个方法签名是相等的。

附注:
如果我表达我的观点,我认为你的Accepter抽象不够合理。我很难解释它的作用。设计一个好的抽象很困难,我相信现有的抽象已经足够满足你的需求——测试你的业务逻辑。

假设你的业务逻辑是解析一个JSON文档并将其转换为可读的文本。你可以将它封装成以下签名的函数:

func DescribeDocument(src io.Reader, dst io.Writer) error {
    ...
}

你可以在生产代码中将实现了net.Conn接口的对象传递给这个函数,或者在测试代码中传递bytes.Buffer对象。没有必要发明不必要的抽象 Go接口:net.Conn不是io.ReadWriteCloser吗?

英文:

I don't believe that stupid questions exist. If there is an honest question, there is an urge for knowledge, and it cannot be stupid by definition Go接口:net.Conn不是io.ReadWriteCloser吗?

Go relies on method signature to decide if two interfaces are the same. You cannot say that two method signatures are equal if they return essentially different types.

P.S.
If I express my opinion, I don't think your Accepter abstraction is sound. I am struggling to explain what it does. Coming up with a good abstraction is hard, and I am pretty sure that the existing abstractions are already enough to do what you want -- test your business logic.

Let's say your business logic parses a JSON document and converts it to a human-readable text. You can pack it to a function with the following signature:

func DescribeDocument(src io.Reader, dst io.Writer) error {
    ...
}

You can pass an object that implements the net.Conn interface to this function in a production code or the bytes.Buffer object in a test code. No need to invent unnecessary abstractions Go接口:net.Conn不是io.ReadWriteCloser吗?

huangapple
  • 本文由 发表于 2022年1月3日 19:01:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/70564776.html
匿名

发表评论

匿名网友

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

确定