文章目錄
- 一 字元
- 二 字元串
- 三 字元串常用操作
- 3.1 len()函數與字元串周遊
- 3.2 string()函數類型轉換
- 3.3 字元串連接配接
- 四 strings包相關函數
- 五 strconv包的字元串轉換函數
一 字元
Golang 中沒有專門的字元類型,如果要存儲單個字元(字母),一般使用 byte 來儲存,且使用單引号包裹。
var c1 byte = 'a'
var c2 byte = '0'
fmt.Println("c1=", c1) //輸出 97
fmt.Println("c2=", c2) //輸出48
fmt.Printf("c1=%c,c2=%c\n", c1, c2) //輸出原值 a 0
//var c3 byte = '北'
//fmt.Printf("c3=%c", c3) // 溢出錯誤:overflows byte
貼士:
- 字元類型也可以用
列印為整型d%
- 如果我們儲存的字元在 ASCII 表的,比如[0-1, a-z,A-Z…]直接可以儲存到 byte
- 如果我們儲存的字元對應碼值大于 255,這時我們可以考慮使用 int 類型儲存
- 如果我們需要安裝字元的方式輸出,這時我們需要格式化輸出,即 fmt.Printf(“%c”, c1)
- 字元可以和整型進行運算
二 字元串
傳統的字元串是由字元組成的,而Go的字元串是由單個位元組連接配接起來的,即Go字元串是一串固定長度的字元連接配接起來的字元序列。
字元串在Go語言中是基本類型,内容在初始化後不能修改。
Go中的字元串都是采用UTF-8字元集編碼,使用一對雙引号
""
或反引号
``
定義。
``
可以額外解析換行,即其沒有字元轉義功能。
var str1 string
str1 = "Hello "
str2 := " World!"
fmt.Println(str1[0]) // 輸出字元串第一個字元 72
fmt.Println(len(str1)) // 輸出長度 6
fmt.Println(str1 + str2) // 輸出不帶空格的
// 字元串不可變,編譯報錯: cannot assign to 因為
// str1[0] = 'c'
由于Go中的字元串不可直接改變,可以使用下列兩種方式進行修改:
方式一:通過轉換為位元組數組
[]byte
類型,構造一個臨時字元串
str := "hello"
strTemp := []byte(str)
fmt.Println("strTemp=", strTemp) // [104 101 108 108 111]
strTemp[0] = 'c'
strResult := string(strTemp)
fmt.Println("strResult=", strResult) // strResult= cello
方式二:使用切片
str := "hello"
str = "c"+ str[1:] // 1: 表示從第1位開始到最後
Go和Java等語言一樣,字元串預設是不可變的,這樣保證了線程安全,大家使用的都是隻讀對象,無須加鎖,且能很友善的共享記憶體,不必使用寫時複制。
三 字元串常用操作
3.1 len()函數與字元串周遊
len()函數是go語言的内建函數,可以用來擷取字元串、切片、通道等的長度。
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str1 := "hello world"
str2 := "你好,"
fmt.Println(len(str1)) // 11
fmt.Println(len(str2)) // 9
fmt.Println(utf8.RuneCountInString(str2)) // 3
}
第一個函數輸出11很容易了解,第二個函數卻輸出了9,理論上我們會認為應該是3才對。這是因為Go的字元串都是以UTF-8格式儲存,每個中文占據3個位元組。Go中計算UTF-8字元串格式的長度應該使用
utf8.RuneCountInString
。
字元串周遊方式一:使用位元組數組,注意每個中文在UTF-8中占據3個位元組
str := "hello"
for i := 0; i < len(str); i++ {
fmt.Println(i,str[i])
}
字元串周遊方式二:range關鍵字隻是第一種周遊方式的簡寫
str := "你好"
for i,ch := range str {
fmt.Println(i,ch)
}
注意:由于上述len()函數本身原因,Unicode字元周遊需要使用range。
3.2 string()函數類型轉換
go的内建函數
string()
可以将其他類型轉變為字元串類型:
num := 12
fmt.Printf("%T \n", string(num)) // string
3.3 字元串連接配接
使用
+
能夠連接配接字元串。但是該操作并不高效(因為字元串在Go中是基本類型,每次拼接都是拷貝了記憶體!)。Go1.10提供了類似Java的StringBuilder機制來進行高效字元串連接配接:
package main
import (
"bytes"
"fmt"
)
func main() {
str1 := "hello "
str2 := " world"
//建立位元組緩沖
var stringBuilder bytes.Buffer
//把字元串寫入緩沖
stringBuilder.WriteString(str1)
stringBuilder.WriteString(str2)
//将緩沖以字元串形式輸出
fmt.Println(stringBuilder.String())
}
在1.10版本前,可以使用bytes.Buffer拼接字元串(因為字元串其實是位元組數組):
var buf bytes.Buffer
buf.WriteString("hello")
fmt.Println(buf.String())
四 strings包相關函數
//查找s在字元串str中的索引
Index(str, s string) int
//判斷str是否包含s
Contains(str, s string) bool
//通過字元串str連接配接切片 s
Join(s []string, str string) string
//替換字元串str中old字元串為new字元串,n表示替換的次數,小于0全部替換
Replace(str,old,new string,n int) string
//字元串str按照s分割,傳回切片
Splite(str,s string)[]string
// 去除頭部、尾部指定的字元串
Trim(s string, cutset string) string
// 去除空格,傳回切片
Fields(s string) []string
五 strconv包的字元串轉換函數
package main
import (
"fmt"
"strconv"
)
func main() {
// Append 系列函數将整數等轉換為字元串後,添加到現有的位元組數組中
str1 := make([]byte, 0, 100)
str1 = strconv.AppendInt(str1, 4567, 10)
str1 = strconv.AppendBool(str1, false)
str1 = strconv.AppendQuote(str1, "abcdefg")
str1 = strconv.AppendQuoteRune(str1, '單')
fmt.Println(string(str1)) // 4567false"abcdefg"'單'
// Format 系列函數把其他類型的轉換為字元串
a := strconv.FormatBool(false)
b := strconv.FormatFloat(123.23, 'g', 12, 64)
c := strconv.FormatInt(1234, 10)
d := strconv.FormatUint(12345, 10)
e := strconv.Itoa(1023)
fmt.Println(a, b, c, d, e) // false 123.23 1234 12345 1023
// Parse 系列函數把字元串轉換為其他類型
f, _ := strconv.ParseBool("false")
g, _ := strconv.ParseFloat("123.23", 64)
h, _ := strconv.ParseInt("1234", 10, 64)
i, _ := strconv.ParseUint("12345", 10, 64)
j, _ := strconv.Atoi("1023")
fmt.Println(f, g, h, j, i, j) // false 123.23 1234 1023 12345 1023
}