天天看點

06-值類型-2-字元串

文章目錄

  • ​​一 字元​​
  • ​​二 字元串​​
  • ​​三 字元串常用操作​​
  • ​​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
}