Go語言字符串

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

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

 

定義字符串

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

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

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

str := `Go原生原格式字符串
            能夠跨行`

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

鏈接字符串

第一種,直接使用 "+" 運算符連接優化

str := "hello" + "oldboy"

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

注意:鏈接跨行字符串時,"+" 必須在上一行末尾,不然致使編譯錯誤。spa

str := "hello" +
        "oldboy" +
        "PythonAV"
    fmt.Println(str)

第二種,使用 fmt.Sprintf() 連接指針

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

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

第三種,使用 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()

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

字符串長度

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

str := "hello oldboy春生"
    length0 := len(str)
    length1 := len([]rune(str))
    fmt.Println(length0,length1)

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

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

func Count(s, sep []byte) int

計算字節切片sep在字節切片s中非重疊顯示的個數,若是 sep 爲 nil,則返回 s 中的字符個數 + 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
鳥宿池邊樹,僧敲月下門。
相關文章
相關標籤/搜索