A piece table never stores the text as one string - it stores a list of pieces that each point into a backing buffer. Today you switch to that representation so the next lessons can insert and delete by splitting pieces.
Represent the buffer as a list of pieces over the original text, with Text and Len computed by walking that list.
A piece table represents text as a sequence of pieces, each of which says
“take Length bytes starting at Start from this backing buffer.” Right now
there is one backing buffer, the immutable original, and one piece covering all
of it, so Text() walks the list and concatenates each piece’s slice back into the
whole string. That looks like a roundabout way to store "hello", and for
unedited text it is - the payoff comes the moment you insert.
Introduce the Piece type at its full shape now, including a Source field, even
though every piece today points at the original. Next lesson adds a second backing
buffer for inserted text, and because the piece already carries its source, that
lesson only has to append a piece rather than reshape this type. Building the
general representation on the first member of the family keeps every later edit a
clean, one-idea addition.
type Source intconst ( Original Source = iota; Add ) // Add is the append buffer, next lessontype Piece struct { Source Source; Start, Length int }// New("hello") -> pieces = [{Original, 0, 5}]// Text() walks pieces, slicing b.original for eachfunc (b *Buffer) Text() string { /* concat content(p) for p in pieces */ }