英文:
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)
你的返回类型与接口定义的不同。仔细看一下错误信息中的have
和want
语句。
英文:
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语言依赖于方法签名来判断两个接口是否相同。如果两个方法签名返回的类型本质上不同,那么你不能说这两个方法签名是相等的。
附注:
如果我表达我的观点,我认为你的Accepter
抽象不够合理。我很难解释它的作用。设计一个好的抽象很困难,我相信现有的抽象已经足够满足你的需求——测试你的业务逻辑。
假设你的业务逻辑是解析一个JSON文档并将其转换为可读的文本。你可以将它封装成以下签名的函数:
func DescribeDocument(src io.Reader, dst io.Writer) error {
...
}
你可以在生产代码中将实现了net.Conn
接口的对象传递给这个函数,或者在测试代码中传递bytes.Buffer
对象。没有必要发明不必要的抽象
英文:
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 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论