這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
背景
學習go已經有很長一段時間了,對於它的資料類型還沒有更加深入的瞭解,這裡做一下對資料類型的總結,第一篇是字串的介紹。
golang中的字串
func stringDemo() { str := "李陽" //len函數返回的是位元組長度 fmt.Println(len(str)) //utf8的RuneCountInString判斷的是ASCII長度 fmt.Println(utf8.RuneCountInString(str))}
字串拼接
在java中我們拼接字串一般怎麼做?用加號拼接、用StringBuffer、用StringBuilder。相對的在go中也有好幾種方法,每種方法效能不一。
通過+進行字串拼接
在go語言中,string在記憶體中的儲存結構是長度固定的位元組數組,也就是說是字串是不可變的。當要修改字串的時候,需要轉換為[]byte,修改完成後再轉換回來。但是不論怎麼轉換,都必須重新分配記憶體,並複製資料。
func appendStrUsePlus() { var s1 = "Hello " var s2 = "World" s3 := s1 + s2 fmt.Println(s3)}
通過加號拼接字串,每次都必須重新分配記憶體。所以如果是頻繁的使用+進行拼接會存在嚴重的效能問題。怎麼解決呢?思路是:預分配足夠大的記憶體空間,也就是我們接下來要說的strings.Join()方法,它會統計所有參數的長度,並一次性完成記憶體的分配操作。
通過strings.join()進行拼接
使用strings中的方法,需要引入strings庫。
func appendStrUseJoin() { s := make([]string, 10) for i := 0; i < 10; i++ { s[i] = "h" } fmt.Println(strings.Join(s, ","))//h,h,h,h,h,h,h,h,h,h}
看一下string.Join()的源碼,第一個參數是一個字串數組,第二個參數是分隔字元,有點類似Java中的StringUtils裡的join方法。
func Join(a []string, sep string) string { if len(a) == 0 { return "" } if len(a) == 1 { return a[0] } n := len(sep) * (len(a) - 1) for i := 0; i < len(a); i++ { n += len(a[i]) } b := make([]byte, n) bp := copy(b, a[0]) for _, s := range a[1:] { bp += copy(b[bp:], sep) bp += copy(b[bp:], s) } return string(b)}
通過buffer進行組裝拼接
使用buffer是優先建立一個緩衝區,然後向緩衝區中寫入資料,類似Java中的StringBuffer。
func appendStrUseBuf() { var b bytes.Buffer b.Grow(100) for i := 0; i < 100; i++ { b.WriteString("a") } fmt.Println(b.String())}
字串分割
在Java中我們有StringUtils.split()方法,在go中也存在類似的方法:strings.split()。
func splitStr() { str := "liyang,liyang,liyang" strs := strings.Split(str, ",") fmt.Println(strs)}
除此之外還有SplitN()、SplitAfter()、SpliteAfterN()方法,不過不是特別常用。
字串截取
字串實際上是一個位元組數組,所以我們可以通過分區的方式來截取字串。
字串轉位元組數組
首先我們來看一段代碼,之前已經提到過,字串實際上是一個位元組數組,所以我們可以像運算元組一樣操作字串的每個位元組。
func strConsole() { str := "liyang" for i := 0; i < len(str); i++ { fmt.Println(string(str[i])) }}
字串預設值
字串預設是是Null 字元串,不是nil。
func stringDefaultVal() {var str stringfmt.Println(str == nil) //invalid operation: str == nil (mismatched types string and nil)fmt.Println(str == "")}
字串儲存結構
在Java中,字串是通過char數組儲存的,所以字串是不可變的。那麼在go語言中字串是怎麼儲存的呢。在go中,字串是不可變的位元組數組,其頭部指標指向一個位元組數組。
字串記憶體配置
字串預設在堆上分配記憶體儲存。