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!
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 :)