介紹
strconv
包實現了基本數據類型和其對應字符串之間的相互轉換。主要有一下常用函數:Atoi
,Itoa
,Parse系列
,Formart系列
,Append系列
string和int之間的轉換
這一種是我們經常使用的,但是我知道包括我在內,尤其是搞python的,肯定都這么干過
package main
import "fmt"
func main() {
num := 97
fmt.Println(string(num)) // a
}
結果發現打印出來的是個a
,因為golang的字符串底層實質上就是一個個字節組成的字節數組,如果使用string(num)
這種方式,那么會將num這個數值對應字符轉成字符串打印出來,而ASCII碼中97和a是對應的的,所以打印了a
Itoa
如果想把int轉成string應該是用Itoa
, i就是integer,這個a是什么?其實這個a就是字符串,只不過這是從C語言中遺留下來的,因為C中沒有字符串的概念,而是使用字符數組,所以這個a在C中是array。但是在go中就把a當中字符串即可
package main
import (
"fmt"
"strconv"
)
func main() {
num := 97
fmt.Println(strconv.Itoa(num)) // 97
fmt.Println(strconv.Itoa(num) == "97") // true
}
Atoi
既然能把整型轉成字符串,那么能不能把字符串轉換為整型呢?顯然是可以的,反過來即可,也就是Atoi
。
package main
import (
"fmt"
"strconv"
)
func main() {
//整型轉字符串可以直接轉,但是字符串轉整型,則是有可能發生錯誤的,因為必須要求字符串的每一個字符必須是數字也可以轉
//所以這里除了返回結果,還會返回一個error
str := "97"
if num , err := strconv.Atoi(str); err != nil {
fmt.Println(err)
} else {
fmt.Println(num) //97
}
str = "97xx"
if num , err := strconv.Atoi(str); err != nil {
fmt.Println(err) //strconv.Atoi: parsing "97xx": invalid syntax
} else {
fmt.Println(num)
}
}
Parse系列函數
Parse類函數用於轉換字符串為給定類型的值:ParseBool
、ParseFloat
、ParseInt
、ParseUint
ParseBool
將指定字符串轉換為對應的bool類型,只接受1、0、t、f、T、F、true、false、True、False、TRUE、FALSE
,否則返回錯誤
package main
import (
"fmt"
"strconv"
)
func main() {
//因為是字符串轉回去,必然可能發生轉化失敗的情況,因此都會多返回一個error
//而這里解析成功了,所以error是nil
fmt.Println(strconv.ParseBool("1")) // true <nil>
fmt.Println(strconv.ParseBool("F")) // false <nil>
}
ParseInt
func ParseInt(s string, base int, bitSize int) (i int64, err error)
s:轉成int的字符串
base:指定進制(2到36),如果base為0,那么會從字符串的前置來判斷,如0x表示16進制等等,如果前綴也沒有那么默認是10進制
bistSize:整數類型,0、8、16、32、64 分別代表 int、int8、int16、int32、int64
返回的err是*NumErr類型的,如果語法有誤,err.Error = ErrSyntax;如果結果超出類型范圍err.Error = ErrRange
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.ParseInt("0x16", 0, 0)) // 22 <nil>
fmt.Println(strconv.ParseInt("16", 16, 0)) // 22 <nil>
fmt.Println(strconv.ParseInt("16", 0, 0)) // 16 <nil>
//這里是八進制,在go 1.13中可以使用0o前綴,但我目前使用的1.12,所以直接使用0作為前綴表示八進制
fmt.Println(strconv.ParseInt("016", 0, 0)) // 14 <nil>
//進制為2,但是字符串出現了6,無法解析
fmt.Println(strconv.ParseInt("16", 2, 0)) // 0 strconv.ParseInt: parsing "16": invalid syntax
//只指定8位,顯然存不下。最后給了一個能存儲的最大的值
fmt.Println(strconv.ParseInt("257", 0, 8)) // 127 strconv.ParseInt: parsing "257": value out of range
//還可以指定正負號
fmt.Println(strconv.ParseInt("-0x16", 0, 0)) // -22 <nil>
fmt.Println(strconv.ParseInt("-016", 0, 0)) // -14 <nil>
}
ParseUnit
ParseUint
類似ParseInt
,但不接受正負號,用於無符號整型。
ParseFloat
func ParseFloat(s string, bitSize int) (f float64, err error)
bitSize:32、64,表示對應精度的float
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.ParseFloat("3.14", 64)) //3.14 <nil>
}
Format系列函數
Format系列函數就比較簡單了,就是將指定數據類型格式化成字符串,Parse則是將字符串解析成指定數據類型,這兩個是相反的。轉成字符串的話,則不需要擔心error了。
FormatBool
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.FormatBool(true)) //true
fmt.Println(strconv.FormatBool(false) == "false") //true
}
FormatInt
傳入字符串和指定的進制
package main
import (
"fmt"
"strconv"
)
func main() {
//數值是22,但是它是16進制的,所以對應成10進制是16
fmt.Println(strconv.FormatInt(22, 16)) //16
}
FormatUint
是FormatInt的無符號版本
FormatFloat
函數將浮點數表示為字符串並返回。
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
f:float64
fmt:fmt表示格式:’f’(-ddd.dddd)、’b’(-ddddp±ddd,指數為二進制)、’e’(-d.dddde±dd,十進制指數)、’E’(-d.ddddE±dd,十進制指數)、’g’(指數很大時用’e’格式,否則’f’格式)、’G’(指數很大時用’E’格式,否則’f’格式)。
prec:prec控制精度(排除指數部分),對’f’、’e’、’E’,它表示小數點后的數字個數;對’g’、’G’,它控制總的數字個數。如果prec 為-1,則代表使用最少數量的、但又必需的數字來表示f。
bitSize:f是哪一種float,32或者64
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.FormatFloat(3.1415, 'f', -1, 64)) //3.1415
fmt.Println(strconv.FormatFloat(3.1415, 'e', -1, 64)) //3.1415e+00
fmt.Println(strconv.FormatFloat(3.1415, 'E', -1, 64)) //3.1415E+00
fmt.Println(strconv.FormatFloat(3.1415, 'g', -1, 64)) //3.1415
}