GoLang string與strings.Builder使用對比詳解
一、strings.Builder的優(yōu)勢
- 以存在的內(nèi)容不可變,但可以拼接更多的內(nèi)容;
- 減少了內(nèi)存分配和內(nèi)存拷貝的次數(shù);
- 可將可容重疊,可重用值;
二、string類型的值
在Go語言中,string類型的值是不可變的。
基于原字符串的裁剪和拼接操作:
- 裁剪操作可以使用切片表達(dá)式;
- 拼接操作可以使用操作符+實(shí)現(xiàn);
一個string的內(nèi)容會被存儲在一塊連續(xù)的內(nèi)存空間中,這個連續(xù)空間的字節(jié)數(shù)量也會被記錄下來,并用于表示該string值的長度。
對string類型的值,執(zhí)行l(wèi)en() 方法,得到的是字節(jié)的數(shù)量。
var str01 string str01 = "Go,你好" // len(string) : 11 fmt.Printf("len(string) : %v \n", len(str01)) // len([]char): 5 fmt.Printf("len([]char): %v\n", len([]rune(str01))) // len([]byte): 11 fmt.Printf("len([]byte): %v\n", len([]byte(str01)))
對string類型的值,進(jìn)行切片操作,相當(dāng)于對底層的字節(jié)數(shù)組做切片
// 在string類型的值上進(jìn)行切片操作,相當(dāng)于對底層的字節(jié)數(shù)組做切片 fmt.Println(str01[0:3]) // Go? fmt.Println(str01[0:5]) // Go,
在執(zhí)行字符串拼接的時候,會把所有被拼接的字符串依次拷貝到一個嶄新且足夠大的連續(xù)內(nèi)存空間中,并把相應(yīng)指針指的string值作為結(jié)果返回。
三、與string相比Builder的優(yōu)勢體現(xiàn)在拼接方面
與string相比,strings.Builder 的優(yōu)勢最要體現(xiàn)在字符串拼接方面。
Builder有一個內(nèi)容容器,它是一個以byte為元素類型的切片(簡稱字節(jié)切片)。
Builder類型的值只能被拼接或完全覆蓋。
3.1 Builder的拼接與Builder的自動擴(kuò)容
可以通過Write、WriteByte、WriteRune、WriteString方法,把新的內(nèi)容拼接到已存在的內(nèi)容的尾部。
Builder會自動地對自身的內(nèi)容容器進(jìn)行擴(kuò)容。擴(kuò)容策略與切片的擴(kuò)容策略一致。
3.2 手動擴(kuò)容
Builder的值還可以手動擴(kuò)容,通過調(diào)用Builder的Grow方法,就可以做到。
Grow方法接受一個int類型的參數(shù)n,這個參數(shù)表示要擴(kuò)充的字節(jié)數(shù)量。
如果未用容量大于或等于n,Grow方法可能什么都不做。
3.3 Builder的重用
通過調(diào)用Reset方法,可以讓Builder值重新回到零值的狀態(tài),就像它從未被使用一樣。
四、strings.Builder的使用約束
- springs.Builder 類型的值在已被真正使用后,就不可再被復(fù)制。
- 由于其內(nèi)容不是完全不可變的,需要使用方自行解決操作沖突和并發(fā)安全的問題。
只要調(diào)用了Builder值的拼接或擴(kuò)容方法,就意味著真正使用。一旦真正使用,Builder值就不能被復(fù)制,否則調(diào)用副本的方法會引起panic。
var sb01 strings.Builder sb01.WriteString("Go") sb02 := sb01 // sb02.Grow(1) // 這里會引起恐慌panic _ = sb02
雖然Builder值不可復(fù)制,但是它的指針指卻可以復(fù)制。復(fù)制的指針值會指向同一個Builder值。
對于處于零值狀態(tài)的Builder值,復(fù)制不會有任何問題。所以,只要在傳遞之前調(diào)用Reset方法即可。
var sb01 strings.Builder sb01.WriteString("Go") sb01.Reset() sb03 := sb01 sb03.Grow(1)
五、strings.Reader類型的值可以高效讀取字符串
strings.Reader 類型的值,可以讓我們很方便的讀取一個字符串中的內(nèi)容。因?yàn)?,在讀取的過程中,Reader值會保存已讀取的字節(jié)的計(jì)數(shù)。
一讀計(jì)數(shù)代表著下次讀取的起始索引位置。
Reader 正是依靠這樣的一個計(jì)數(shù),以及針對字符串的切片表達(dá)式,從而實(shí)現(xiàn)快讀讀取。
通過Len方法和Size方法獲取已讀計(jì)數(shù):
var reader1 strings.Reader reader1 = *strings.NewReader("Go, 你好") ch, size, err := reader1.ReadRune() fmt.Printf("%v, %v, %v\n", string(ch), size, err) readingIndex := reader1.Size() - int64(reader1.Len()) fmt.Printf("以讀計(jì)數(shù):%v\n", readingIndex)
Reader 的Seek方法用于設(shè)定下一次讀取的起始索引位置;如果把io.SeekCurrent 的值作為第二個參數(shù)值傳遞給該方法。那么它會依據(jù)當(dāng)前的已讀計(jì)數(shù),以及第一個參數(shù)offset的值來計(jì)算新的計(jì)數(shù)值。
到此這篇關(guān)于GoLang string與strings.Builder使用對比詳解的文章就介紹到這了,更多相關(guān)Go string與strings.Builder內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang如何實(shí)現(xiàn)mapreduce單進(jìn)程版本詳解
這篇文章主要給大家介紹了關(guān)于golang如何實(shí)現(xiàn)mapreduce單進(jìn)程版本的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01我放棄Python轉(zhuǎn)Go語言的9大理由(附優(yōu)秀書籍推薦)
這篇文章主要給大家介紹了關(guān)于我放棄Python轉(zhuǎn)Go語言的9大理由,以及給大家推薦了6本優(yōu)秀的go語言書籍,對同樣想學(xué)習(xí)golang的朋友們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10golang sql連接池的實(shí)現(xiàn)方法詳解
database/sql是golang的標(biāo)準(zhǔn)庫之一,它提供了一系列接口方法,用于訪問關(guān)系數(shù)據(jù)庫。下面這篇文章主要給大家介紹了關(guān)于golang sql連接池用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧2018-09-09