What separates a buffer from a byte array or slice? Are buffers just a fancy array?

xuanbao · · 492 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>This is one part of Go I&#39;m having trouble understanding. A buffer is an ordered collection of bytes. Some functions read data into buffers, or out of buffers, and I can make a new buffer out of a []byte.</p> <p>One new thing is that a buffer stores a marker of the &#39;current position&#39;, and has a <code>Next</code> method that reads <em>n</em> bytes from the marker while advancing it. Okay. And they have a <code>ReadFrom</code> which reads from a data source until it indicates EOF, and stores it in the buffer.</p> <p>Is that essentially all it is? Is <code>Buffer</code> a struct that stores a slice/array of bytes and a current-position marker, with a few methods added? Is the purpose of a buffer to represent some data I might read or write in chunks rather than all at once? </p> <p>I&#39;d welcome any advice/explanations. I bought a book on Go and devoured it, and I&#39;m enjoying learning the language, the core language features all clicked for me on day one, but the stdlib is giving me some trouble with things like this.</p> <hr/>**评论:**<br/><br/>earthboundkid: <pre><p>Use the source, Luke: <a href="https://golang.org/src/bytes/buffer.go#L17" rel="nofollow">https://golang.org/src/bytes/buffer.go#L17</a></p></pre>verisimilarity: <pre><p>Yes, a Buffer is just what you said: a struct that contains a byte slice (probably) and metadata. It also gives useful functions for buffer operations, like you said. </p> <p>It&#39;s nothing super special; it&#39;s just a nice abstraction built without any fancy new language features like you&#39;d find in less elegant languages for less civilized ages ;)</p></pre>rimpy13: <pre><p>Buffer is a high level idea.</p> <p>One way to implement one is to use a byte array/slice as the data container.</p> <p>Your question is similar to asking “what separates a vehicle from a motorcycle?”</p></pre>ask: <pre><p>Fancy arrays, just like integers are just fancy bits (etc). :-)</p></pre>hobbified: <pre><p>Because Buffer has Read, Write, ReadFrom, and WriteTo methods, it implements several of the useful <a href="https://golang.org/pkg/io/" rel="nofollow">io</a> interfaces (Reader, Writer, ReadWriter, ReaderFrom, WriterTo), which means that you can use it with all kinds of core and non-core functions that deal with those interfaces. If you wrap it with ioutil.NopCloser it can also do Closer, ReadCloser, WriteCloser, and ReadWriteCloser. It&#39;s &#34;just&#34; a type to adapt a <code>[]byte</code> to all of those interfaces so that you can use it in places you would otherwise use a file or socket. Although if you look at the source as <a href="/u/earthboundkid" rel="nofollow">/u/earthboundkid</a> suggests you&#39;ll see that it&#39;s not exactly trivial.</p> <p>There&#39;s also bytes.Reader, which is similar except for two things:</p> <ol> <li>It doesn&#39;t have any of the writing methods, and won&#39;t modify the underlying <code>[]byte</code> (and, of course, doesn&#39;t do Writer, ReadWriter, or ReaderFrom).</li> <li>It does have Seek and ReadAt methods, which means that it additionally works as a Seeker, ReadSeeker, and ReaderAt.</li> </ol> <p>In theory there&#39;s no reason why there couldn&#39;t be a single type that combined the features of both and acted as a ReadWriteSeeker, but the Go maintainers have never given a shit for orthogonality, and doing that would complicate the implementation, so we don&#39;t get that one :)</p></pre>earthboundkid: <pre><p>How would a Buffer with Seek work? In a normal Buffer, reads are one time only, so it would be pretty different if you could seek too. </p></pre>hobbified: <pre><p>Like a file rather than like a pipe. Reading moves the pointer but doesn&#39;t drop the data. Which, yeah, is another reason you wouldn&#39;t want to use it most of the time.</p></pre>earthboundkid: <pre><p>That would be a nice type to have. Bytes.Buffer returns the backing slice, so if you give that to bytes.Reader, it won’t allocate. That will let you seek but not write. A new type for seek writing might be nice too. </p></pre>djherbis: <pre><p>My lib <a href="https://godoc.org/github.com/djherbis/buffer" rel="nofollow">djherbis/buffer</a> has a type called <a href="https://godoc.org/github.com/djherbis/buffer#BufferAt" rel="nofollow">BufferAt</a> which implements io.ReaderAt/io.WriterAt so you can read/write from/to different places in the buffer.</p> <p>You can get a BufferAt using <a href="https://godoc.org/github.com/djherbis/buffer#New" rel="nofollow">buffer.New</a> which is backed by bytes.Buffer.</p></pre>dilap: <pre><p>So Go helpfully has the nice, simple interfaces io.Reader and io.Writer, for anything that can be read from or written to.</p> <p>bytes.Buffer is simply the answer to the question, &#34;how would I implement these interfaces writing and writing to and from a byte-slice?&#34;</p></pre>

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

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