簡介
字串在各種程式語言中都是很基礎的一種型別,在Go
中字串簡單理解就是一個陣列,陣列裡面的元素是byte
型別。因此基本上擁有類似陣列的全部特性。例如len
可以返回字串的位元組數,注意不是字元的長度:
s := "go"
fmt.Println(len(s)) //2
也可以根據下標訪問該位置的位元組
s := "go"
fmt.Println(s[0]) //103 字元g的ASCII碼
字串也可以類似切片的操作,取其給定範圍內的字串,生成一個新的字元
s := "hello world"
fmt.Println(s[0:5]) // "hello"
fmt.Println(s[:5]) // "hello"
fmt.Println(s[:]) // "hello world"
也可以用+
操作符,把兩個字串連線成一個新的字串
s := "hello"
w := "world"
s = s + w //"hello world"
剛開始的時候我們說過,字串是不可變,這段程式碼中最後的s
是一段新的字串。而不是在開始s
基礎上修改的。同時先要做類似陣列那樣修改元素的值也是不可以的
s := "hello"
s[1] = 't' //編譯時會報錯
UTF-8字元
UTF-8
是UNICODE
的一種變長度的編碼表達方式,我們都知道ASCII
編碼是1個位元組,但是這也限制了它只能代表128個字元,無非對其它語言的字元進行編碼。如果把所有的字元都用統一用32位表示,的確比較簡單,但是這樣會浪費很多空間,而且歷史上的ASCII
編碼的字元也無相容。UTF-8
採用1-4個位元組表示字元,ASCII
還是隻用1個位元組,保持相容。如果第一個位元組的是110
開頭,則需要2個位元組。1110開頭則需要3個位元組,11110開頭則是4個位元組。
0xxxxxxx runes 0-127 (ASCII)
110xxxxx 10xxxxxx 128-2047 (values <128 unused)
1110xxxx 10xxxxxx 10xxxxxx 2048-65535 (values <2048 unused)
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 65536-0x10ffff (other values unused)
Go
的string
就是採用UTF-8
編碼,因此無法直接通過下標i
直接訪問第i
個字元,比如:
s := "你好世界"
fmt.Println(len(s)) //15
上面這段程式碼執行返回長度是12,如果想要知道有多少個字元可以利用unicode/utf8
提供的功能來獲取:
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "你好世界!"
fmt.Println(len(s)) //15
fmt.Println(utf8.RuneCountInString(s)) //5
}
想要分割成單個字元輸出可以通過for range
:
func main() {
s := "你好世界!"
for i, r := range s {
fmt.Printf("%d\t%q\t%d\n", i, r, r)
}
}
//返回
0 '你' 20320
3 '好' 22909
6 '世' 19990
9 '界' 30028
12 '!' 65281
這次遍歷都是單個字元的遍歷,而不是單個位元組。
字串的常用操作
Go
的標準庫提供了豐富的工具,對字串進行操作,下面簡單介紹下常見的操作:
package main
import (
"fmt"
"strings"
)
func main() {
s := "hello"
fmt.Println(strings.Contains(s, "he")) //true 是否包含子字串
fmt.Println(strings.Replace(s, "he", "eh", 1)) // ehllo 替換第一個
bytes := []byte(s) //轉化為byte陣列
s2 := string(bytes)//byte陣列轉化為字串
fmt.Println(s2)
}
字串和數字之間的轉化也是經常用到的,strconv
裡面提供的豐富的功能讓它們互相轉化
import (
"fmt"
"strconv"
)
func main() {
s := "123"
i, _:= strconv.Atoi(s) //字串轉化為數字
fmt.Println(i+2) //125
x := 123
var a string = strconv.Itoa(x) //數字轉化為字串
fmt.Println(a) //123
}
如果想要動態的增加字串Go
提供了Buffer
型別可以動態的增加字元:
package main
import (
"fmt"
"bytes"
)
func main() {
var buf bytes.Buffer
buf.WriteString("s")
fmt.Println(buf.String()) //s
buf.WriteByte('A')
fmt.Println(buf.String()) //sA
}