strings.Builder類型的值(以下簡稱Builder值)的優勢有下面的三種:
已存在的內容不可變,但可以拼接更多的內容;
減少了內存分配和內容拷貝的次數;
可將內容重置,可重用值。
先來說說string類型。
我們都知道,在 Go 語言中,string類型的值是不可變的。 如果我們想獲得一個不一樣的字符串,那么就只能基於原字符串進行裁剪、拼接等操作,從而生成一個新的字符串。裁剪操作可以使用切片表達式;拼接操作可以用操作符+實現。
因為string類型底層是數組,每次擴容都需要重新分配內存,性能是有損耗的
Builder值的優勢其實主要體現在字符串拼接方面
Builder值中有一個用於承載內容的容器(以下簡稱內容容器)。它是一個以byte為元素類型的切片(以下簡稱字節切片)。
切片可以預分配容量,因此不需要反復分配內存
由於這樣的字節切片的底層數組就是一個字節數組,所以我們可以說它與string值存儲內容的方式是一樣的。
實際上,它們都是通過一個unsafe.Pointer類型的字段來持有那個指向了底層字節數組的指針值的。
var builder1 strings.Builder builder1.WriteString("A Builder is used to efficiently build a string using Write methods.") fmt.Printf("The first output(%d):\n%q\n", builder1.Len(), builder1.String()) fmt.Println() builder1.WriteByte(' ') builder1.WriteString("It minimizes memory copying. The zero value is ready to use.") builder1.Write([]byte{'\n', '\n'}) builder1.WriteString("Do not copy a non-zero Builder.") fmt.Printf("The second output(%d):\n\"%s\"\n", builder1.Len(), builder1.String()) fmt.Println() // 示例2。 fmt.Println("Grow the builder ...") builder1.Grow(10) //擴容字節切片 fmt.Printf("The length of contents in the builder is %d.\n", builder1.Len()) fmt.Println() // 示例3。 fmt.Println("Reset the builder ...") builder1.Reset() //重置內容 fmt.Printf("The third output(%d):\n%q\n", builder1.Len(), builder1.String())