溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

GoLang?string與strings.Builder使用源碼對比分析

發(fā)布時間:2023-03-17 14:23:59 來源:億速云 閱讀:243 作者:iii 欄目:開發(fā)技術

本文小編為大家詳細介紹“GoLang string與strings.Builder使用源碼對比分析”,內容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“GoLang string與strings.Builder使用源碼對比分析”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

    一、strings.Builder的優(yōu)勢

    • 以存在的內容不可變,但可以拼接更多的內容;

    • 減少了內存分配和內存拷貝的次數(shù);

    • 可將可容重疊,可重用值;

    二、string類型的值

    在Go語言中,string類型的值是不可變的。

    基于原字符串的裁剪和拼接操作:

    • 裁剪操作可以使用切片表達式;

    • 拼接操作可以使用操作符+實現(xiàn);

    一個string的內容會被存儲在一塊連續(xù)的內存空間中,這個連續(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類型的值,進行切片操作,相當于對底層的字節(jié)數(shù)組做切片

    	// 在string類型的值上進行切片操作,相當于對底層的字節(jié)數(shù)組做切片
    	fmt.Println(str01[0:3]) // Go?
    	fmt.Println(str01[0:5]) // Go,

    在執(zhí)行字符串拼接的時候,會把所有被拼接的字符串依次拷貝到一個嶄新且足夠大的連續(xù)內存空間中,并把相應指針指的string值作為結果返回。

    三、與string相比Builder的優(yōu)勢體現(xiàn)在拼接方面

    與string相比,strings.Builder 的優(yōu)勢最要體現(xiàn)在字符串拼接方面。

    Builder有一個內容容器,它是一個以byte為元素類型的切片(簡稱字節(jié)切片)。

    Builder類型的值只能被拼接或完全覆蓋。

    3.1 Builder的拼接與Builder的自動擴容

    可以通過Write、WriteByte、WriteRune、WriteString方法,把新的內容拼接到已存在的內容的尾部。

    Builder會自動地對自身的內容容器進行擴容。擴容策略與切片的擴容策略一致。

    3.2 手動擴容

    Builder的值還可以手動擴容,通過調用Builder的Grow方法,就可以做到。

    Grow方法接受一個int類型的參數(shù)n,這個參數(shù)表示要擴充的字節(jié)數(shù)量。

    如果未用容量大于或等于n,Grow方法可能什么都不做。

    3.3 Builder的重用

    通過調用Reset方法,可以讓Builder值重新回到零值的狀態(tài),就像它從未被使用一樣。

    四、strings.Builder的使用約束

    • springs.Builder 類型的值在已被真正使用后,就不可再被復制。

    • 由于其內容不是完全不可變的,需要使用方自行解決操作沖突和并發(fā)安全的問題。

    只要調用了Builder值的拼接或擴容方法,就意味著真正使用。一旦真正使用,Builder值就不能被復制,否則調用副本的方法會引起panic。

    	var sb01 strings.Builder
    	sb01.WriteString("Go")
    	sb02 := sb01
    	// sb02.Grow(1) // 這里會引起恐慌panic
    	_ = sb02

    雖然Builder值不可復制,但是它的指針指卻可以復制。復制的指針值會指向同一個Builder值。

    對于處于零值狀態(tài)的Builder值,復制不會有任何問題。所以,只要在傳遞之前調用Reset方法即可。

    	var sb01 strings.Builder
    	sb01.WriteString("Go")
        sb01.Reset()
    	sb03 := sb01
    	sb03.Grow(1)

    五、strings.Reader類型的值可以高效讀取字符串

    strings.Reader 類型的值,可以讓我們很方便的讀取一個字符串中的內容。因為,在讀取的過程中,Reader值會保存已讀取的字節(jié)的計數(shù)。

    一讀計數(shù)代表著下次讀取的起始索引位置。

    Reader 正是依靠這樣的一個計數(shù),以及針對字符串的切片表達式,從而實現(xiàn)快讀讀取。

    通過Len方法和Size方法獲取已讀計數(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("以讀計數(shù):%v\n", readingIndex)

    Reader 的Seek方法用于設定下一次讀取的起始索引位置;如果把io.SeekCurrent 的值作為第二個參數(shù)值傳遞給該方法。那么它會依據(jù)當前的已讀計數(shù),以及第一個參數(shù)offset的值來計算新的計數(shù)值。

    讀到這里,這篇“GoLang string與strings.Builder使用源碼對比分析”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業(yè)資訊頻道。

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

    AI