go - `bufio.Writer` 还是 `io.Writer`?

标签 go interface

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

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

最佳答案

创建您的函数以接受 io.Writer,并记录它将写入大量数据,因此 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)
}

但通常这种包装仅在需要“超出”io.Writer 的额外功能时应用。

关于go - `bufio.Writer` 还是 `io.Writer`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48115577/

相关文章:

mysql - Golang - 从 MySQL 检索多个结果,然后将它们显示为 JSON

java - 如何正确设计界面

Java:使用符合我的接口(interface)的外部类

c++ - 如何获取 C++ 接口(interface) VMT 的地址

.net - 使用标记接口(interface)而不是属性的令人信服的理由

java - 我的类用方法实现接口(interface)。未实现但没有错误

go - 将符号定义为 UserID 还是 UserId?

go - 无效的内存地址或 nil 指针与 mgo 取消引用

go - 如何在函数中多次添加一些行?

pointers - 使用嵌套结构指针断言接口(interface)