Go 中 strconv 包的类型转换
go package main
import ( "fmt" "strconv" )
func main() { // 解析十进制字符串 i, err := strconv.ParseInt("255", 10, 64) if err != nil { panic(err) } fmt.Println(i) // 255
// 自动识别进制:0x开头按十六进制,0开头按八进制
i2, _ := strconv.ParseInt("0xFF", 0, 64)
fmt.Println(i2) // 255
}
第三个参数 `bitSize` 指定结果必须能放入对应大小的整数类型中(0, 8, 16, 32, 64),否则会返回错误。
### ParseUint:解析无符号整数
用法与 `ParseInt` 类似,但返回值是 `uint64`。
```go
u, err := strconv.ParseUint("42", 10, 64)
if err != nil {
// 处理错误
}
fmt.Println(u) // 42
ParseFloat:解析浮点数字符串
strconv.ParseFloat 将字符串解析为浮点数,第二个参数 bitSize 可以是 32 或 64,对应 float32 或 float64 精度。
f, err := strconv.ParseFloat("3.1415", 64)
if err != nil {
panic(err)
}
fmt.Println(f) // 3.1415
该函数可以解析科学计数法格式的字符串,如 "6.022e23"。
ParseBool:解析布尔字符串
接受 "1", "t", "T", "true", "TRUE", "True" 返回 true;"0", "f", "F", "false", "FALSE", "False" 返回 false。其他字符串会触发错误。
b, err := strconv.ParseBool("true")
fmt.Println(b, err) // true <nil>
数值转换为字符串:Format 系列函数
将数值格式化为字符串的显示形式,常用于日志输出、拼接或序列化。
FormatInt 与 FormatUint
strconv.FormatInt 将 int64 按指定进制转换为字符串。进制参数范围为 2~36。
s := strconv.FormatInt(255, 16) // "ff"
s2 := strconv.FormatInt(-42, 10) // "-42"
strconv.FormatUint 用于 uint64,注意无符号数不会有负号。
s := strconv.FormatUint(255, 2) // "11111111"
FormatFloat:浮点数格式化
这是 Format 系列中最灵活的函数,通过多个参数控制输出格式:
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
fmt:格式标记。常用值:'f':普通小数形式(-ddd.dddd)'e'/'E':科学计数法'g'/'G':根据情况自动选择'e'或'f'
prec:精度控制。对'f'表示小数点后位数;对'e'表示总位数;对'g'表示最大总位数。bitSize:帮助函数正确舍入,通常传入 64(即使底层是 float32 也传 64 较安全)。
f := 3.1415926535
fmt.Println(strconv.FormatFloat(f, 'f', 2, 64)) // "3.14"
fmt.Println(strconv.FormatFloat(f, 'e', 4, 64)) // "3.1416e+00"
fmt.Println(strconv.FormatFloat(f, 'g', 5, 64)) // "3.1416"
FormatBool
布尔转字符串非常简单,返回 "true" 或 "false"。
s := strconv.FormatBool(true) // "true"
简便转换:Atoi 与 Itoa
为了方便整数与十进制字符串的互转,strconv 提供了两个快捷函数。
Atoi:字符串转 int
Atoi 等价于 ParseInt(s, 10, 0),但返回的是 int 类型(与平台相关)。是日常编程中最常用的数字解析函数。
i, err := strconv.Atoi("42")
if err != nil {
// 处理非数字字符串
}
fmt.Println(i) // 42
Itoa:int 转字符串
Itoa 等价于 FormatInt(int64(i), 10)。
s := strconv.Itoa(42) // "42"
带引号的字符串转换:Quote 与 Unquote
当你需要处理带双引号的 Go 字面字符串时,可以使用 Quote 和 Unquote。
Quote 与 QuoteToASCII
strconv.Quote 返回一个被双引号包围的 Go 字符串字面量,其中的特殊字符会被转义。
s := strconv.Quote("Hello\nWorld")
// 输出:"Hello\nWorld" (包含外围双引号)
QuoteToASCII 会将非 ASCII 字符转义为 Unicode 转义序列。
s := strconv.QuoteToASCII("你好")
// 输出:"\u4f60\u597d"
Unquote
Unquote 将带引号的字符串字面量还原为原始字符串。它还能正确解析单引号括起来的字符字面量。
raw, err := strconv.Unquote(`"Hello\nWorld"`)
if err == nil {
fmt.Println(raw) // Hello
// World
}
错误处理与 NumError
所有 Parse 函数在转换失败时都会返回错误,实际类型是 *strconv.NumError。通过类型断言可以区分具体原因:
func main() {
_, err := strconv.Atoi("abc")
if err != nil {
if numErr, ok := err.(*strconv.NumError); ok {
fmt.Println("转换失败:", numErr.Err)
}
}
}
NumError 包含三个字段:Func (函数名)、Num (原始字符串)、Err (具体原因,如 strconv.ErrSyntax 或 strconv.ErrRange)。了解错误类型有助于进行精确的错误处理。
Append 系列函数:高效字符串构建
为避免频繁的字符串分配,strconv 提供了 Append* 系列函数。它们将转换结果追加到现有的 []byte 切片后面,并返回扩展后的切片。
buf := []byte("Result: ")
buf = strconv.AppendInt(buf, 123, 10)
buf = append(buf, ", "...)
buf = strconv.AppendFloat(buf, 3.14, 'f', 2, 64)
fmt.Println(string(buf)) // Result: 123, 3.14
类似的有 AppendBool、AppendQuote 等,在拼接大量字符串时能显著提升性能。
实际应用案例
从请求参数中解析数字
func GetPageNumber(s string) (int, error) {
page, err := strconv.Atoi(s)
if err != nil {
return 1, fmt.Errorf("invalid page number: %v", err)
}
if page < 1 {
page = 1
}
return page, nil
}
安全格式化用户输入的浮点数显示
func FormatPrice(raw string) (string, error) {
f, err := strconv.ParseFloat(raw, 64)
if err != nil {
return "", err
}
// 保留两位小数显示
return strconv.FormatFloat(f, 'f', 2, 64), nil
}