我有一个函数可以将数据写入任何使用Write(b []byte) (n int, err error)
方法实现接口的内容。现在在我的程序中,我写了一个实际的Conn
,但遵循最佳实践(https://dave.cheney.net/2016/08/20/solid-go-design),因为我只调用Write
,我想接受实现该方法的最小接口。为此,我接受带有接口io.Writer
的参数。
由于我的功能可以非常快速地输出大量数据,我应该接受bufio.Writer
吗?或者功能的消费者责任是使用缓冲编写器而不是普通编写器?什么是最佳实践?
答案 0 :(得分:6)
创建您的函数以接受io.Writer
和文档它将写入大量数据,因此建议{em}建议1}}或类似的构造
不要将您的功能用户限制为bufio.Writer
,因为您只使用bufio.Writer
的功能。用户也可以拥有io.Writer
的其他“缓冲”实现,这对他们来说已经足够了。
不要决定对图书馆用户有什么好处,让他们决定什么对他们有好处。如果用户发现io.Writer
比bufio.Writer
实施更有用或更好,他们可以始终将其包裹在io.Writer
中并传递(仅使用bufio.Writer
)。
如果您创建的函数接受bufio.NewWriter(w)
,用户可以使用单行实用程序函数轻松添加包装功能:
io.Writer
如果您创建的函数接受func wrapAndPass(w io.Writer) {
yourFunction(bufio.NewWriter(w))
}
,则用户无法撤消此“包装”。无论是否需要,用户都将被迫始终创建并传递bufio.Writer
。
此外,您可以选择提供两个功能:您的原始功能采用bufio.Writer
,以及上述包装和传递实用程序功能。如果你这样做,那么检查传递的编写器是否已经是io.Writer
也是很好的,在这种情况下应该避免包装。像这样:
*bufio.Writer
但通常只有在“超出”func wrapIfNeededAndPass(w io.Writer) {
if _, ok := w.(*bufio.Writer); !ok {
w = bufio.NewWriter(w)
}
yourFunction(w)
}
之外需要额外功能时才会应用此类包装。