Go基礎數據結構學習——string
-
string在Go語言內存模型中用一個2字長的數據結構表示,一個是指向字符串存儲的數據的指針,另一個爲長度數據。
type stringStruct struct { str unsafe.Pointer len int }
-
由於string中不包含內存空間,只有一個內存的指針,可以方便的進行傳輸而不用擔心內存拷貝,非常的輕量化,但是字符串字面量存儲位置是隻讀段的,不是在堆或者棧上,所以string是不可修改的
-
string和[]byte相互轉換,需要內存拷貝(申請內存空間=>拷貝數據),[]byte擅長與字符串修改和切片操作的場景,string擅長與字符串比較和不需要nil的場景
-
注意:
-
string默認值是“”,而不是nil
-
string不能和nil比較
-
len獲取到的是字符串的字節數而不是字符串的字符數
對於ascii字符,一個字符佔一個字節;對於非ASCII字符,比如漢字,一個字符就佔3個字節。如字符串“hello北京”,它的字符長度是7,但它的字節長度是11
-
Index遍歷的時候也是字節遍歷的,所以中文遍歷會有亂碼問題
-
for-range是字符遍歷的,不會出現亂碼,但是下標index就有出現不連續的問題
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FPcw0B45-1586877765381)(/Users/hexiaohong/Library/Application Support/typora-user-images/image-20200414224923063.png)]
-
-
字符串的拼接
字符串的評價有很多種方式,比如:
-
使用“+”
hello := "hello" world := "world" helloWorld := hello + "," + world // 每次+都會產生新的臨時字符串,會給 gc 帶來負擔,性能比較差
-
使用fmt.Sprintf
hello := "hello" world := "world" helloWorld := fmt.Sprintf("%s,%s", hello, world) // 可以用於有數字或其他的拼接,因爲其他的額外判斷,性能也比較差
-
strings.Join()
hello := "hello" world := "world" helloWorld := strings.Join([]string{hello, world}, ",") // join會先根據字符串數組,計算出一個拼接之後的長度,然後申請對應大小的內存,一個一個字符串填入,在已有一個數組的情況下,這種效率會很高
-
使用buffer.WriteString()
hello := "hello" world := "world" var buffer bytes.Buffer buffer.WriteString(hello) buffer.WriteString(",") buffer.WriteString(world) helloWorld := buffer.String() // 性能最好
-