【问题标题】:Go interfaces: is not net.Conn a io.ReadWriteCloser?Go 接口:net.Conn 不是 io.ReadWriteCloser 吗?
【发布时间】:2022-01-03 11:01:38
【问题描述】:

我有一个关于 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 lib 源代码,我看到 net.Conn 实际上是在实现 io.ReadWriteCloser

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

【问题讨论】:

  • 您的Accepter“规定”返回类型为io.ReadWriteClosernet.Listener.Accept() 返回net.Conn。类型必须完全匹配。

标签: go network-programming go-interface


【解决方案1】:

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

    错误准确地告诉你问题是什么:

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

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

    【讨论】:

    • 谢谢,我理解错误消息,我怀疑 go 处理接口的方式:net.Conn 对象也应该是 - 根据定义 - io.ReadWriteCloser 接口。因此,我不明白为什么编译器会抱怨。无论我想对 ReadWriteCloser (RWC) 对象执行什么操作,我都应该能够在 net.Conn 实现上执行。举个例子:我可以创建一个 RWC 频道并在那里传递一个 net.Conn 没有任何问题;我在这里也有同样的期待。
    猜你喜欢
    • 1970-01-01
    • 2018-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 2021-04-18
    • 2011-09-08
    • 2014-11-19
    相关资源
    最近更新 更多