學習筆記Go語言 4.字典、字串
技術標籤:go
學習筆記Go語言 4.字典、字串
4.1 字典
map是一種較為特殊的資料結構(鍵值對結構),通過給定的key可以快速獲得對應的value。
4.1.1 如何定義字典
var m1 map[string]int
m2 := make(map[int]interface{}, 100)
m3 := map[string]string{
''name'':''james'',
''age'':''35'',
}
定義字典時不需要為其指定容量,因為map是可以動態增長的,但是在可以預知map容量的情況下為了提高程式的效率也最好提前標明程式的容量。需要注意的是,不能使用不能比較的元素作為字典的key,例如陣列,切片等。而value可以是任意型別的,如果使用interface{}作為value型別,那麼就可以接受各種型別的值,只不過在具體使用的時候需要使用型別斷言來判斷型別。
m3['key1']='v1' //向字典中放入元素:
len(m3)//獲取字典的長度
判斷鍵值對是否存在(value是否為空)
if value,ok := m3[''name''];ok{
fmt.Println(value)
}
上面這段程式碼的作用就是如果當前字典中存在key為name的字串則取出對應的value,並返回true,否則返回false。
遍歷字典:
for key,value:=range m3{
fmt.Println('key:',key,'value:',value)
}
上面這段程式每次的輸出順序並不相同,這是因為對於一個字典來說,預設其是無序的。
(可通過切片使字典有序)
刪除字典中的值:使用go的內建函式delete
delete(m3,'key1')
將函式作為值型別存入字典:
func main(){
m := make(map[string]func(a, b int) int)
m["add"] = func(a, b int) int {
return a + b
}
m["multi"] = func(a, b int) int {
return a * b
}
fmt.Println(m["add"](3, 2))
fmt.Println(m["multi" ](3, 2))
}
4.2 字串
4.2.1字串定義
字串是一種值型別,在建立字串之後其值是不可變的。
要修改一個字串的內容,可以將其轉換為位元組切片,再將其轉換為字串,但同樣需要重新分配記憶體。
func main(){
s :='hello'
b :=[]byte(s)
b[0]='g'
s=string(b)
fmt.Println(s)//gello
}
len(s) //獲取字串長度
但如果字串中包含中文就不能直接使用byte切片對其進行操作,go語言中我們可以通過這種方式
func main(){
s := "hello你好中國"
fmt.Println(len(s)) //17
fmt.Println(utf8.RuneCountInString(s)) //9
b := []byte(s)
for i := 0; i < len(b); i++ {
fmt.Printf("%c", b[i])
} //helloä½ å¥½ä¸å�½
fmt.Println()
r := []rune(s)
for i := 0; i < len(r); i++ {
fmt.Printf("%c", r[i])
} //hello你好中國
}
在go語言中字串都是以utf-8的編碼格式進行儲存的,所以每個中文佔三個位元組加上hello的5個位元組所以長度為17,如果我們通過utf8.RuneCountInString函式獲得的包含中文的字串長度則與我們的直覺相符合。而且由於中文對於每個單獨的位元組來說是不可列印的,所以可以看到很多奇怪的輸出,但是將字串轉為rune切片則沒有問題。
4.2.2 strings包
strings包提供了許多操作字串的函式。在這裡你可以看到都包含哪些函式,連結: https://golang.org/pkg/strings/.
func main() {
var str string = "This is an example of a string"
//判斷字串是否以Th開頭
fmt.Printf("%t\n", strings.HasPrefix(str, "Th"))
//判斷字串是否以aa結尾
fmt.Printf("%t\n", strings.HasSuffix(str, "aa"))
//判斷字串是否包含an子串
fmt.Printf("%t\n", strings.Contains(str, "an"))
}
4.2.3 strconv包
strconv包實現了基本資料型別與字串之間的轉換。在這裡你可以看到都包含哪些函式連結: https://golang.org/pkg/strconv/.
i, err := strconv.Atoi("-42") //將字串轉為int型別
s := strconv.Itoa(-42) //將int型別轉為字串
若轉換失敗則返回對應的error值
4.2.4 字串拼接
1.Sprintf
const numbers = 100
func BenchmarkSprintf(b *testing.B) {
b.ResetTimer()
for idx := 0; idx < b.N; idx++ {
var s string
for i := 0; i < numbers; i++ {
s = fmt.Sprintf("%v%v", s, i)
}
}
b.StopTimer()
}
2.+拼接
func BenchmarkStringAdd(b *testing.B) {
b.ResetTimer()
for idx := 0; idx < b.N; idx++ {
var s string
for i := 0; i < numbers; i++ {
s += strconv.Itoa(i)
}
}
b.StopTimer()
}
3.bytes.Buffer
func BenchmarkBytesBuf(b *testing.B) {
b.ResetTimer()
for idx := 0; idx < b.N; idx++ {
var buf bytes.Buffer
for i := 0; i < numbers; i++ {
buf.WriteString(strconv.Itoa(i))
}
_ = buf.String()
}
b.StopTimer()
}
4.strings.Builder拼接
func BenchmarkStringBuilder(b *testing.B) {
b.ResetTimer()
for idx := 0; idx < b.N; idx++ {
var builder strings.Builder
for i := 0; i < numbers; i++ {
builder.WriteString(strconv.Itoa(i))
}
_ = builder.String()
}
b.StopTimer()
}
5.對比
BenchmarkSprintf-8 68277 18431 ns/op
BenchmarkStringBuilder-8 1302448 922 ns/op
BenchmarkBytesBuf-8 884354 1264 ns/op
BenchmarkStringAdd-8 208486 5703 ns/op