<p>Right now, there is a ReadWriter in bufio, which takes a bufio.Reader and bufio.Writer and creates a bufio.ReadWriter which satisfies the io.ReadWriter interface.</p>
<p>This is extremely useful, especially for mocking. I created a Protocol handler that would accept any ReadWriter and read/write a custom protocol from/to it. To mock this, I had to create two bytes.Buffer's, and wrap them in a bufio.Reader/bufio.Writer pair, which I could use to create a bufio.ReadWriter. </p>
<p>However, I didn't want them to be buffered. The Protocol handler already buffers them, so in mocking I had to manually flush them to access them from the original bytes.Buffer's.</p>
<p>So I believe io should have a NewReadWriter function as well, which directly wraps any Reader and Writer, and the one in bufio should remain where it is because buffered readers/writers have different interfaces. It's very easy to code a more generic ReadWriter, it takes about 5 lines of code, but it bugs me that it's not in the stdlib when bufio.ReadWriter is.</p>
<p>Anyone agree?</p>
<p>Edit: Code example</p>
<p>To combine a Reader and Writer into a ReadWriter, I currently have to do this:</p>
<pre><code>sample := bytes.NewBuffer(nil)
target := bytes.NewBuffer(nil)
buf := bufio.NewReadWriter(bufio.NewReader(sample), bufio.NewWriter(target))
sample.Write([]byte{6, 0, 3})
sample.WriteTo(buf) // In reality, my "decoder" would be reading from 'sample' and writing to 'target'
buf.Writer.Flush()
log.Println(target.Bytes())
</code></pre>
<p>But if they defined this in io:</p>
<pre><code>type ReadWriter struct {
io.Reader
io.Writer
}
</code></pre>
<p>Then just do this:</p>
<pre><code>sample := bytes.NewBuffer(nil)
target := bytes.NewBuffer(nil)
buf := io.ReadWriter{sample, target}
sample.Write([]byte{6, 0, 3})
sample.WriteTo(target) // In reality, my "decoder" would be reading from 'sample' and writing to 'target'
log.Println(target.Bytes())
</code></pre>
<p>This saves a bufio.Reader, a bufio.Writer, and a bufio.Writer.Flush.</p>
<hr/>**评论:**<br/><br/>lstokeworth: <pre><p>It's one line of code:</p>
<pre><code> rw := struct { io.Reader; io.Writer }{r, w}
</code></pre>
<p>See <a href="http://play.golang.org/p/ZtGiN1DMGC" rel="nofollow">this code in the playground</a></p>
<p>Edit based on your edit: Just do this:</p>
<pre><code>var sample, target bytes.Buffer // bonus line reduction by using zero value of buffer
buf := struct { io.Reader; io.Writer }{ &sample, &target}
sample.Write([]byte{6, 0, 3})
sample.WriteTo(&target) // In reality, my "decoder" would be reading from 'sample' and writing to 'target'
log.Println(target.Bytes())
</code></pre></pre>danredux: <pre><p>Definitely, but same could be said for bufio.ReadWriter, no?</p>
<pre><code>brw := struct{Reader: *bufio.Reader;Writer: *bufio.Writer}{r,w}
</code></pre></pre>lstokeworth: <pre><p>Both packages declare an ReadWriter type. The difference is that one package defines interfaces and the other declares concrete types.</p></pre>TheMerovius: <pre><p>No, you can't, for example, call <code>Buffered()</code> on that.</p></pre>TheMerovius: <pre><p>Okay, "for example" is overstated, that seems to be the only thing that doesn't work :)</p></pre>TheMerovius: <pre><p>Also, that's literally the same thing bufio already does. So… yes, you're right :)</p></pre>danredux: <pre><p>Haha I like you. :P</p></pre>Fwippy: <pre><p>I'm really not sure what you're asking. You go through a lot of trouble to construct your <code>buf</code> and then you never use it in your example code. </p>
<p>If you want special behavior linked to the ReadWriter (i.e: written data is available to the reader, or data should be copied from the reader to the writer), what kind of behavior are you asking for? <code>bytes.Buffer</code> already fulfills the <code>io.ReadWriter</code> interface, and writes to it can later be read. <code>io.Pipe()</code> can be used to construct the reverse. that is, to send all data from a Reader to a Writer.</p>
<p>If you're not asking for them to implement any particular behavior (just one reader and one writer), just package them up in a struct as <a href="/u/lstokeworth" rel="nofollow">/u/lstokeworth</a> suggests.</p></pre>albatr0s: <pre><p>Are you trying to emulate Node.js streams in Go?</p></pre>danredux: <pre><p>No? I'm trying to emulate bufio.NewReadWriter in io.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传