`bufio.Writer`或`io.Writer`?

时间:2018-01-05 14:26:55

标签: go interface

我有一个函数可以将数据写入任何使用Write(b []byte) (n int, err error)方法实现接口的内容。现在在我的程序中,我写了一个实际的Conn,但遵循最佳实践(https://dave.cheney.net/2016/08/20/solid-go-design),因为我只调用Write,我想接受实现该方法的最小接口。为此,我接受带有接口io.Writer的参数。

由于我的功能可以非常快速地输出大量数据,我应该接受bufio.Writer吗?或者功能的消费者责任是使用缓冲编写器而不是普通编写器?什么是最佳实践?

1 个答案:

答案 0 :(得分:6)

创建您的函数以接受io.Writer文档它将写入大量数据,因此建议{em}建议

不要将您的功能用户限制为bufio.Writer,因为您只使用bufio.Writer的功能。用户也可以拥有io.Writer的其他“缓冲”实现,这对他们来说已经足够了。

不要决定对图书馆用户有什么好处,让他们决定什么对他们有好处。如果用户发现io.Writerbufio.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) } 之外需要额外功能时才会应用此类包装。