github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/coding/bufio/00-read-rune.go (about)

     1  package main
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"strings"
     8  )
     9  
    10  // A StringReader delivers its data one string segment at a time via Read.
    11  type StringReader struct {
    12  	data []string
    13  	step int
    14  }
    15  
    16  // 在将reader数据读取到缓存buf时 会用到这个read
    17  // 这个read step 默认为1 表示每次读取step个字符, 起始值为0
    18  func (r *StringReader) Read(p []byte) (n int, err error) {
    19  	if r.step < len(r.data) {
    20  		s := r.data[r.step]
    21  		n = copy(p, s)
    22  		r.step++
    23  	} else {
    24  		err = io.EOF // 读取结束
    25  	}
    26  	return
    27  }
    28  
    29  func readRuneSegments(segments []string) {
    30  	got := ""
    31  	want := strings.Join(segments, "")
    32  	r := bufio.NewReader(&StringReader{data: segments})
    33  	for {
    34  		r, _, err := r.ReadRune()
    35  		if err != nil {
    36  			if err != io.EOF {
    37  				return
    38  			}
    39  			break
    40  		}
    41  		got += string(r)
    42  	}
    43  	if got != want {
    44  		fmt.Errorf("segments=%v got=%s want=%s", segments, got, want)
    45  	}
    46  }
    47  
    48  var segmentList = [][]string{
    49  	{},
    50  	{""},
    51  	{"日", "本語"},
    52  	{"\u65e5", "\u672c", "\u8a9e"},
    53  	{"\U000065e5", "\U0000672c", "\U00008a9e"},
    54  	{"\xe6", "\x97\xa5\xe6", "\x9c\xac\xe8\xaa\x9e"},
    55  	{"Hello", ", ", "World", "!"},
    56  	{"Hello", ", ", "", "World", "!"},
    57  }
    58  
    59  func main() {
    60  	for _, s := range segmentList {
    61  		readRuneSegments(s)
    62  	}
    63  }