GO語言字符串有哪些?詳細分類

  編程語言有很多,而每個編程語言都離不開字符串,那麼你知道GO語言字符串有哪些嗎?我們一起來看看吧。

  Go語言的字符串是一個用UTF-8編碼的變寬字符序列,它的每一個字符都用一個或多個字節表示 。

  在Go語言中,沒有字符類型,字符類型是rune類型,rune是int32的別稱。可使用 []byte() 獲取字節,使用 []rune() 獲取字符,可對中文進行轉換。

  定義字符串

  第一種,雙引號,用來創建可解析的字符串字面量 (支持轉義,但不能用來引用多行);

  str := "Go語言字符串\n不能跨行賦值"

  第二種,反引號,用來創建原生的字符串字面量 ,這些字符串可能由多行組成(不支持任何轉義序列),原生的字符串字面量多用於書寫多行消息、HTML以及正則表達式。

  str := `Go原生原格式字符串

  可以跨行`

  注意:單引號不能用於定義字符串,單引號用於定義Go語言的一個特殊類型 rune,類似其他語言的byte但又不完全一樣,是指碼點字面量(Unicode code point),不做任何轉義的原始內容。

  連接字符串

  第一種,直接使用 "+" 運算符鏈接

  str := "hello" + "oldboy"

  golang 裏面的字符串都是不可變的,每次運算都會產生一個新的字符串,所以會產生很多臨時的無用的字符串,不僅沒有用,還會給 gc 帶來額外的負擔,所以性能比較差。

  注意:連接跨行字符串時,"+" 必須在上一行末尾,否則導致編譯錯誤。

  第二種,使用 fmt.Sprintf() 鏈接

  str := fmt.Sprintf("%s,%s", "hello", "oldboy")

  內部使用 []byte 實現,不像直接運算符這種會產生很多臨時的字符串,但是內部的邏輯比較複雜,有很多額外的判斷,還用到了 interface,所以性能也不是很好。

  第三種,使用 strings.Join() 鏈接

  str := strings.Join([]string{"hello", "oldboy"}, ",")

  join會先根據字符串數組的內容,計算出一個拼接之後的長度,然後申請對應大小的內存,一個一個字符串填入,在已有一個數組的情況下,這種效率會很高,但是本來沒有,去構造這個數據的代價也不小。

  第四種,使用 buffer.WriteString() 鏈接

  var buffer bytes.Buffer

  buffer.WriteString("hello")

  buffer.WriteString(",")

  buffer.WriteString("oldboy")

  str := buffer.String()

  這個比較理想,可以當成可變字符使用,對內存的增長也有優化。

  總結:

  1. 在已有字符串數組的場合,使用 strings.Join() 能有比較好的性能;

  2. 在一些性能要求較高的場合,儘量使用 buffer.WriteString() 以獲得更好的性能;

  3. "+" 運算符在較少字符串連接的場景下性能最好,而且代碼更簡短清晰,可讀性更好;

  4. 如果需要拼接的不僅僅是字符串,還有數字之類的其他需求的話,可以考慮 fmt.Sprintf()。

  字符串長度

  第一種,將字符串轉換爲 []rune 後調用 len 函數進行統計

  package main

  import (

  "fmt"

  )

  func main() {

  str := "hello oldboy"

  length := len([]rune(str))

  fmt.Println(length)

  }

  在 Golang 中,如果字符串中出現中文字符不能直接調用 len 函數來統計字符串字符長度,這是因爲在 Go 中,字符串是以 UTF-8 爲格式進行存儲的,在字符串上調用 len 函數,取得的是字符串包含的 byte 的個數。

  第二種,使用 bytes.Count() 統計

  func Count(s, sep []byte) int

  計算字節切片sep在字節切片s中非重疊顯示的個數,如果 sep 爲 nil,則返回 s 中的字符個數 + 1。

  package main

  import (

  "bytes"

  "fmt"

  )

  func main() {

  str := "hello oldboy"

  length := bytes.Count([]byte(str), nil) - 1

  fmt.Println(length)

  }

  第三種,使用 strings.Count() 統計

  func Count(s, sep string) int

  判斷字符sep在字符串s中出現的次數,沒有找到則返回-1,如果爲空字符串("")則返回字符串的長度+1。

  package main

  import (

  "fmt"

  "strings"

  )

  func main() {

  str := "hello oldboy"

  length := strings.Count(str, "") - 1

  fmt.Println(length)

  }

  第四種,使用 utf8.RuneCountInString() 統計

  func RuneCountInString(s string) (n int)

  返回 s 字符串長度,可以正常解析中文,一箇中文被當做一個字符。

  package main

  import (

  "fmt"

  "unicode/utf8"

  )

  func main() {

  str := "hello oldboy"

  length := utf8.RuneCountInString(str)

  fmt.Println(length)

  }

  字符串操作

  使用索引號 "[ ]" 返回子串。 返回的字符串依然指向原字節數組,僅修改了指針和長度屬性。實例如下:

  package main

  import (

  "fmt"

  )

  func main() {

  str := "hello, oldboy"

  s1 := str[0:5]

  s2 := str[7:13]

  fmt.Println(s1, s2)

  }

  運行結果:

  hello oldboy

  修改字符串,可先將其轉換成 []rune 或 []byte,完成後再轉換爲 string。無論哪種轉換,都會重新分配內存,並複製字節數組。實例如下:

  package main

  import "fmt"

  func main() {

  str1 := "hello oldboy"

  s1 := []byte(str1)

  s1[0] = 'H'

  fmt.Println(string(s1))

  str2 := "鳥宿池邊樹,僧推月下門。"

  s2 := []rune(str2)

  s2[7] = '敲'

  fmt.Println(string(s2))

  }

  運行結果:

  Hello oldboy

  鳥宿池邊樹,僧敲月下門。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章