0

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

我正在玩一个接受和处理 TCP 连接的小应用程序。因为我想测试业务逻辑而不是网络魔法,所以我试图使用接口保持一点抽象(这样我就可以使用简单的对象模拟 net.Connio.ReadWriteCloser对象)。

这是我的问题:

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 lib 源代码,我发现它net.Conn实际上是在实现io.ReadWriteCloser.

我的错误是什么?非常感谢!

4

2 回答 2

1

该错误准确地告诉您问题所在:

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

您的返回时间与您的界面定义的不同。再看一下错误消息havewant语句。

于 2022-01-03T11:26:45.863 回答
1

我不相信愚蠢的问题存在。如果有一个诚实的问题,就会有求知的冲动,从定义上说它不可能是愚蠢的:)

Go 依赖方法签名来确定两个接口是否相同。如果两个方法签名返回本质上不同的类型,就不能说它们是相等的。

PS如果我表达我的意见,我认为你的Accepter抽象是不合理的。我正在努力解释它的作用。提出一个好的抽象很难,我很确定现有的抽象已经足以满足您的需求——测试您的业务逻辑。

假设您的业务逻辑解析 JSON 文档并将其转换为人类可读的文本。您可以将其打包到具有以下签名的函数中:

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

您可以将实现net.Conn接口的对象传递给生产代码中的此函数或bytes.Buffer测试代码中的对象。无需发明不必要的抽象:)

于 2022-01-03T12:21:10.557 回答