IO通道与读写器

huangapple go评论80阅读模式
英文:

IO channels vs reader/writer

问题

由于Go语言具有通道(channels),我想知道为什么标准库似乎没有被设计成也使用通道进行IO操作。

相反,标准库中有读取器(reader)和写入器(writer)类型,但使用通道会有什么问题呢?

一个函数可以返回一个字节切片的通道(假设单字节甚至单比特的返回效率太低),并接收一个用于取消请求的通道和一个用于错误报告的通道。

  • 好奇的Go初学者。
英文:

Since Go has channels, I was wondering why the standard library doesn't appear to have been designed to use them for IO as well.

There are reader and writer types for that instead but what would be the problem with using channels?

A function could return a channel of byte slices (assuming single-byte, or even single-bit returns are too inefficient) and take in a channel for cancellation requests and a channel for error reporting.

-The curious Go novice.

答案1

得分: 12

通道非常适合在goroutine之间进行通信。当程序执行简单的操作时,例如读取stdin,对流进行处理并将结果输出到stdout时,使用通道是一种过度设计,会不必要地降低性能。

只要标准库没有提供特定于goroutine之间通信的功能,就没有好的理由使用通道来模拟简单的操作,比如io.Readerio.Writer的操作,或者使用基于通道的方法集(API)。

此外,如果需要,可以将简单的实现包装在通道中,但是将通道实现“解包”回其原始形式是不可能的。此外,Go的作者显然喜欢明确性,这导致性能瓶颈不会被隐藏起来(并且令人惊讶)。

英文:

Channels are a good fit for communicating between goroutines. When a program does something simple, like for example reading stdin, doing something with the stream and outputting the result to stdout - then using a channel is an overkill, unnecessarily hurting performance.

As long as the standard library doesn't provide in some place something specific to goroutines communicating with each other, there's no good reason to model simple operations, like those of io.Reader or io.Writer using channels, respective to have a channel based method set (API).

Additionally, where needed, the simple implementation can be wrapped in a channel, while the opposite, to "unwrap" a channel implementation back to its primitive is not possible. Also, Go authors obviously like explicitness, leading to performance bottlenecks not being hidden (and surprising).

答案2

得分: 1

我认为io.Readerio.Writer存在的另一个原因是它们在单线程级别上表现良好;通道几乎专门用于协程间通信或多线程模型。虽然有些情况下可以互换使用,但它们的设计目的是解决两个不同的问题。
io.Readerio.Writer还具有EOF的概念,这在通道中很难复制,除非在通道上叠加一个单独的协议 - 当然这只会增加额外的负担。
另外,关闭通道并不等同于EOF,因为关闭通道会阻止其在将来被使用。

英文:

I think another reason io.Reader and io.Writer exist is because they play well at the single thread level; channels are almost exclusively for inter-goroutine communication, or multithreaded models. There are cases where you may be able to use them interchangeably, but they were designed to solve 2 different challenges.
io.Reader and io.Writer also have the concept of EOF which cannot be easily replicated with channels, unless you layer a separate protocol over the channel - which of course would just be an overkill.
P.S. closing the channel is not the same as EOF either since closing the channel prevents it from being used in the future.

答案3

得分: 1

这个包实现了将io.Reader和io.Writer包装成通道的功能。

换句话说,它创建了一个线程安全的缓冲区。

换句话说,它是一个通用的管道。

https://github.com/latitov/milkthisbuffer

英文:

This package of mine implements the wrapping of io.Reader and io.Writer into a channel.

Or, in other words, it creates a thread-safe buffer.

Or, in other words, it is a universal pipe.

https://github.com/latitov/milkthisbuffer

huangapple
  • 本文由 发表于 2012年12月2日 17:36:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/13668036.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定