Should there be a ReadWriter in io?

agolangf · · 568 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<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&#39;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&#39;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&#39;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&#39;s very easy to code a more generic ReadWriter, it takes about 5 lines of code, but it bugs me that it&#39;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 &#34;decoder&#34; would be reading from &#39;sample&#39; and writing to &#39;target&#39; 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 &#34;decoder&#34; would be reading from &#39;sample&#39; and writing to &#39;target&#39; 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&#39;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 }{ &amp;sample, &amp;target} sample.Write([]byte{6, 0, 3}) sample.WriteTo(&amp;target) // In reality, my &#34;decoder&#34; would be reading from &#39;sample&#39; and writing to &#39;target&#39; 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&#39;t, for example, call <code>Buffered()</code> on that.</p></pre>TheMerovius: <pre><p>Okay, &#34;for example&#34; is overstated, that seems to be the only thing that doesn&#39;t work :)</p></pre>TheMerovius: <pre><p>Also, that&#39;s literally the same thing bufio already does. So… yes, you&#39;re right :)</p></pre>danredux: <pre><p>Haha I like you. :P</p></pre>Fwippy: <pre><p>I&#39;m really not sure what you&#39;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&#39;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&#39;m trying to emulate bufio.NewReadWriter in io.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

568 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传