Go基礎數據結構學習——string

Go基礎數據結構學習——string

  1. string在Go語言內存模型中用一個2字長的數據結構表示,一個是指向字符串存儲的數據的指針,另一個爲長度數據。

    type stringStruct struct {
    	str unsafe.Pointer
    	len int
    }
    
  2. 由於string中不包含內存空間,只有一個內存的指針,可以方便的進行傳輸而不用擔心內存拷貝,非常的輕量化,但是字符串字面量存儲位置是隻讀段的,不是在堆或者棧上,所以string是不可修改的

  3. string和[]byte相互轉換,需要內存拷貝(申請內存空間=>拷貝數據),[]byte擅長與字符串修改和切片操作的場景,string擅長與字符串比較和不需要nil的場景

  4. 注意:

    • 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)]

  5. 字符串的拼接

    字符串的評價有很多種方式,比如:

    • 使用“+”

      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()
      // 性能最好
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章