golang strings.NewReader

爲何說strings.Reader類型的值能夠高效地讀取字符串ui

與strings.Builder類型偏偏相反,strings.Reader類型是爲了高效讀取字符串而存在的。後者的高效主要體如今它對字符串的讀取機制上,它封裝了不少用於在string值上讀取內容的最佳實踐。spa

strings.Reader類型的值(如下簡稱Reader值)可讓咱們很方便地讀取一個字符串中的內容。在讀取的過程當中,Reader值會保存已讀取的字節的計數(如下簡稱已讀計數)。code

已讀計數也表明着下一次讀取的起始索引位置。Reader值正是依靠這樣一個計數,以及針對字符串值的切片表達式,從而實現快速讀取。blog

此外,這個已讀計數也是讀取回退和位置設定時的重要依據。雖然它屬於Reader值的內部結構,但咱們仍是能夠經過該值的Len方法和Size把它計算出來的索引

Reader值擁有的大部分用於讀取的方法都會及時地更新已讀計數。好比,ReadByte方法會在讀取成功後將這個計數的值加1。ci

又好比,ReadRune方法在讀取成功以後,會把被讀取的字符所佔用的字節數做爲計數的增量。字符串

不過,ReadAt方法算是一個例外。它既不會依據已讀計數進行讀取,也不會在讀取後更新它。正由於如此,這個方法能夠自由地讀取其所屬的Reader值中的任何內容。string

// 示例1。
    reader1 := strings.NewReader(
        "中文的的的SimpleNewReader returns a new Reader reading from s. " +
            "It is similar to bytes.NewBufferString but more efficient and read-only. ")
%d\n",reader1.Size()-int64(reader1.Len()))
    fmt.Printf("len:%d\n",reader1.Len()) //原始字符串長度是141
    by:= make([]byte,20)
    reader1.ReadAt(by,2) //這個方法不作計數也就是原值不變也就是len長度仍是原始長度

    buf1 := make([]byte, 3) //原值偏移量+3 len長度要-3
     reader1.Read(buf1)
    fmt.Printf("len:%d value:%s\n",reader1.Len(),string(buf1))

打印結果爲it

len:141
len:138 value:中 io

除此以外,Reader值的Seek方法也會更新該值的已讀計數。實際上,這個Seek方法的主要做用正是設定下一次讀取的起始索引位置

offset2 := int64(17)
expectedIndex := reader1.Size() - int64(reader1.Len()) + offset2
fmt.Printf("Seek with offset %d and whence %d ...\n", offset2, io.SeekCurrent)
readingIndex, _ := reader1.Seek(offset2, io.SeekCurrent)
fmt.Printf("The reading index in reader: %d (returned by Seek)\n", readingIndex)
fmt.Printf("The reading index in reader: %d (computed by me)\n", expectedIndex)
相關文章
相關標籤/搜索