strconv 包详解
概述
strconv 包实现了基本数据类型和其字符串表示之间的转换。
核心功能:
- 数字转换(int、uint、float、complex、bool 与 string 互转)
- 格式化数字为字符串
- 解析字符串为数字
- 字符串引用和反引用
- Append 系列函数(高效追加到字节切片)
重要说明:
- ✅ Go 版本:所有 Go 版本都支持
- ✅ 错误处理:返回
*NumError类型错误 - ✅ 性能优化:Append 系列函数避免内存分配
包导入
import "strconv"
常量和变量
IntSize
const IntSize = 32 or 64
功能: int 或 uint 类型的位大小。
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Printf("int is %d bits\n", strconv.IntSize)
// 32 位系统:int is 32 bits
// 64 位系统:int is 64 bits
}
ErrRange
var ErrRange = errors.New("value out of range")
功能: 表示值超出目标类型范围。
ErrSyntax
var ErrSyntax = errors.New("invalid syntax")
功能: 表示值的语法不正确。
错误类型
NumError
type NumError struct {
Func string // 失败的函数名
Num string // 导致错误的输入
Err error // 底层错误(ErrSyntax 或 ErrRange)
}
方法:
Error() string- 错误描述Unwrap() error- 返回底层错误
示例:
package main
import (
"errors"
"fmt"
"strconv"
)
func main() {
_, err := strconv.ParseInt("abc", 10, 64)
var numErr *strconv.NumError
if errors.As(err, &numErr) {
fmt.Printf("函数:%s\n", numErr.Func)
fmt.Printf("输入:%s\n", numErr.Num)
fmt.Printf("错误:%v\n", numErr.Err)
}
}
运行结果:
函数:ParseInt
输入:abc
错误:invalid syntax
函数详解(按 A-Z 分类)
A
AppendBool
func AppendBool(dst []byte, b bool) []byte
功能: 根据 b 的值追加 “true” 或 “false” 到 dst。
参数:
dst []byte- 目标字节切片b bool- 布尔值
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
dst := []byte("bool:")
dst = strconv.AppendBool(dst, true)
fmt.Println(string(dst)) // bool:true
}
AppendFloat
func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte
功能: 将浮点数 f 的字符串形式追加到 dst。
参数:
dst []byte- 目标字节切片f float64- 浮点数fmt byte- 格式(‘b’、‘e’、‘E’、‘f’、‘g’、‘G’)prec int- 精度bitSize int- 浮点数类型(32 或 64)
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
pi := 3.1415926535
// float32
dst := strconv.AppendFloat([]byte("float32:"), pi, 'E', -1, 32)
fmt.Println(string(dst))
// float64
dst = strconv.AppendFloat([]byte("float64:"), pi, 'E', -1, 64)
fmt.Println(string(dst))
}
运行结果:
float32:3.1415927E+00
float64:3.1415926535E+00
AppendInt
func AppendInt(dst []byte, i int64, base int) []byte
功能: 将整数 i 的字符串形式追加到 dst。
参数:
dst []byte- 目标字节切片i int64- 整数base int- 进制(2-36)
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
dst := strconv.AppendInt([]byte("decimal:"), 42, 10)
fmt.Println(string(dst)) // decimal:42
dst = strconv.AppendInt([]byte("hex:"), 42, 16)
fmt.Println(string(dst)) // hex:2a
}
AppendQuote
func AppendQuote(dst []byte, s string) []byte
功能: 将字符串 s 的双引号 Go 字符串字面量追加到 dst。
参数:
dst []byte- 目标字节切片s string- 要引用的字符串
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
dst := strconv.AppendQuote([]byte("quoted:"), "Hello\nWorld")
fmt.Println(string(dst)) // quoted:"Hello\nWorld"
}
AppendQuoteRune
func AppendQuoteRune(dst []byte, r rune) []byte
功能: 将 rune 的单引号 Go 字符字面量追加到 dst。
参数:
dst []byte- 目标字节切片r rune- 要引用的字符
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
dst := strconv.AppendQuoteRune([]byte("rune:"), 'A')
fmt.Println(string(dst)) // rune:'A'
}
AppendQuoteRuneToASCII
func AppendQuoteRuneToASCII(dst []byte, r rune) []byte
功能: 将 rune 的 ASCII 单引号字面量追加到 dst(非 ASCII 字符使用 \u 转义)。
参数:
dst []byte- 目标字节切片r rune- 要引用的字符
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
dst := strconv.AppendQuoteRuneToASCII([]byte("ascii:"), '世')
fmt.Println(string(dst)) // ascii:'\u4e16'
}
AppendQuoteRuneToGraphic
func AppendQuoteRuneToGraphic(dst []byte, r rune) []byte
功能: 将 rune 的可打印单引号字面量追加到 dst。
参数:
dst []byte- 目标字节切片r rune- 要引用的字符
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
dst := strconv.AppendQuoteRuneToGraphic([]byte("graphic:"), 'A')
fmt.Println(string(dst)) // graphic:'A'
}
AppendQuoteToASCII
func AppendQuoteToASCII(dst []byte, s string) []byte
功能: 将字符串 s 的 ASCII 双引号字面量追加到 dst(非 ASCII 字符使用 \u 转义)。
参数:
dst []byte- 目标字节切片s string- 要引用的字符串
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
dst := strconv.AppendQuoteToASCII([]byte("ascii:"), "Hello, 世界")
fmt.Println(string(dst)) // ascii:"Hello, \u4e16\u754c"
}
AppendQuoteToGraphic
func AppendQuoteToGraphic(dst []byte, s string) []byte
功能: 将字符串 s 的可打印双引号字面量追加到 dst。
参数:
dst []byte- 目标字节切片s string- 要引用的字符串
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
dst := strconv.AppendQuoteToGraphic([]byte("graphic:"), "Hello")
fmt.Println(string(dst)) // graphic:"Hello"
}
AppendUint
func AppendUint(dst []byte, i uint64, base int) []byte
功能: 将无符号整数 i 的字符串形式追加到 dst。
参数:
dst []byte- 目标字节切片i uint64- 无符号整数base int- 进制(2-36)
返回值:
[]byte- 扩展后的字节切片
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
dst := strconv.AppendUint([]byte("decimal:"), 42, 10)
fmt.Println(string(dst)) // decimal:42
dst = strconv.AppendUint([]byte("hex:"), 42, 16)
fmt.Println(string(dst)) // hex:2a
}
Atoi
func Atoi(s string) (int, error)
功能: 将字符串转换为 int 类型(10 进制)。
参数:
s string- 要转换的字符串
返回值:
int- 转换后的整数error- 错误
注意:
- 是
ParseInt(s, 10, 0)的简写 - 返回 Go int 类型(32 位或 64 位)
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
i, err := strconv.Atoi("-42")
if err != nil {
fmt.Println("转换失败:", err)
return
}
fmt.Println(i) // -42
}
C
CanBackquote
func CanBackquote(s string) bool
功能: 报告字符串 s 是否可以表示为单行反引号字符串。
参数:
s string- 要检查的字符串
返回值:
bool- 是否可以使用反引号
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.CanBackquote("Hello World")) // true
fmt.Println(strconv.CanBackquote("Hello\nWorld")) // false(包含换行)
}
F
FormatBool
func FormatBool(b bool) string
功能: 根据 b 的值返回 “true” 或 “false”。
参数:
b bool- 布尔值
返回值:
string- 字符串表示
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.FormatBool(true)) // true
fmt.Println(strconv.FormatBool(false)) // false
}
FormatComplex
func FormatComplex(c complex128, fmt byte, prec, bitSize int) string
功能: 将复数转换为字符串。
参数:
c complex128- 复数fmt byte- 格式(‘b’、‘e’、‘E’、‘f’、‘g’、‘G’)prec int- 精度bitSize int- 类型(32 或 64)
返回值:
string- 复数的字符串表示
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
c := complex(3.14, 2.71)
s := strconv.FormatComplex(c, 'f', -1, 128)
fmt.Println(s) // (3.14+2.71i)
}
FormatFloat
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
功能: 将浮点数转换为字符串。
参数:
f float64- 浮点数fmt byte- 格式:'b'- 二进制指数(-ddddp±ddd)'e'- 十进制指数小写(-d.dddde±dd)'E'- 十进制指数大写(-d.ddddE±dd)'f'- 定点表示(-ddd.dddd)'g'- 指数大时用 ‘e’,否则用 ‘f’'G'- 指数大时用 ‘E’,否则用 ‘f’
prec int- 精度:- 对 ‘e’、‘E’、‘f’:小数点后的位数
- 对 ‘g’、‘G’:总位数
- -1:使用最少数量的数字
bitSize int- 浮点数类型(32 或 64)
返回值:
string- 浮点数的字符串表示
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
pi := 3.1415926535
// 不同格式
fmt.Println(strconv.FormatFloat(pi, 'f', 2, 64)) // 3.14
fmt.Println(strconv.FormatFloat(pi, 'e', 2, 64)) // 3.14e+00
fmt.Println(strconv.FormatFloat(pi, 'E', 2, 64)) // 3.14E+00
fmt.Println(strconv.FormatFloat(pi, 'f', -1, 64)) // 3.1415926535
fmt.Println(strconv.FormatFloat(pi, 'g', -1, 64)) // 3.1415926535
}
FormatInt
func FormatInt(i int64, base int) string
功能: 返回整数 i 的 base 进制字符串表示。
参数:
i int64- 整数base int- 进制(2-36)
返回值:
string- 整数的字符串表示
注意:
- 使用小写字母 ‘a’-‘z’ 表示 10-35
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
n := int64(42)
fmt.Println(strconv.FormatInt(n, 2)) // 101010(二进制)
fmt.Println(strconv.FormatInt(n, 8)) // 52(八进制)
fmt.Println(strconv.FormatInt(n, 10)) // 42(十进制)
fmt.Println(strconv.FormatInt(n, 16)) // 2a(十六进制)
}
FormatUint
func FormatUint(i uint64, base int) string
功能: 返回无符号整数 i 的 base 进制字符串表示。
参数:
i uint64- 无符号整数base int- 进制(2-36)
返回值:
string- 无符号整数的字符串表示
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
n := uint64(42)
fmt.Println(strconv.FormatUint(n, 2)) // 101010
fmt.Println(strconv.FormatUint(n, 16)) // 2a
}
I
IsGraphic
func IsGraphic(r rune) bool
功能: 检查 rune 是否为可打印字符(包括空格)。
参数:
r rune- 要检查的字符
返回值:
bool- 是否为可打印字符
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.IsGraphic('A')) // true
fmt.Println(strconv.IsGraphic('\n')) // false
fmt.Println(strconv.IsGraphic(' ')) // true
fmt.Println(strconv.IsGraphic('世')) // true
}
IsPrint
func IsPrint(r rune) bool
功能: 检查 rune 是否为可打印字符(不包括空格)。
参数:
r rune- 要检查的字符
返回值:
bool- 是否为可打印字符
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.IsPrint('A')) // true
fmt.Println(strconv.IsPrint('\n')) // false
fmt.Println(strconv.IsPrint(' ')) // false
}
Itoa
func Itoa(i int) string
功能: 将 int 转换为字符串(10 进制)。
参数:
i int- 整数
返回值:
string- 字符串表示
注意:
- 是
FormatInt(i, 10)的简写
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
s := strconv.Itoa(-42)
fmt.Println(s) // -42
}
P
ParseBool
func ParseBool(str string) (bool, error)
功能: 将字符串转换为 bool 值。
参数:
str string- 要转换的字符串
返回值:
bool- 布尔值error- 错误
接受的字符串:
- 真:1、t、T、true、True、TRUE
- 假:0、f、F、false、False、FALSE
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
b, err := strconv.ParseBool("true")
if err != nil {
fmt.Println("转换失败:", err)
return
}
fmt.Println(b) // true
b, _ = strconv.ParseBool("1")
fmt.Println(b) // true
b, _ = strconv.ParseBool("FALSE")
fmt.Println(b) // false
}
ParseComplex
func ParseComplex(s string, bitSize int) (complex128, error)
功能: 将字符串转换为复数。
参数:
s string- 要转换的字符串bitSize int- 类型(32 或 64)
返回值:
complex128- 复数error- 错误
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
c, err := strconv.ParseComplex("(3.14+2.71i)", 128)
if err != nil {
fmt.Println("转换失败:", err)
return
}
fmt.Println(c) // (3.14+2.71i)
}
ParseFloat
func ParseFloat(s string, bitSize int) (float64, error)
功能: 将字符串转换为浮点数。
参数:
s string- 要转换的字符串bitSize int- 浮点数类型(32 或 64)
返回值:
float64- 浮点数值error- 错误
注意:
- bitSize=32:结果可以无损转换为 float32
- bitSize=64:标准 float64
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
f, err := strconv.ParseFloat("3.1415", 64)
if err != nil {
fmt.Println("转换失败:", err)
return
}
fmt.Println(f) // 3.1415
// float32
f32, _ := strconv.ParseFloat("3.14", 32)
fmt.Println(float32(f32)) // 3.14
}
ParseInt
func ParseInt(s string, base int, bitSize int) (i int64, err error)
功能: 将字符串转换为有符号整数。
参数:
s string- 要转换的字符串base int- 进制(2-36,0 表示自动检测)bitSize int- 目标类型大小(0、8、16、32、64)
返回值:
int64- 整数值error- 错误
base 参数:
- 0:自动检测(“0x”=16,“0”=8,其他=10)
- 2-36:指定进制
bitSize 参数:
- 0:int
- 8:int8
- 16:int16
- 32:int32
- 64:int64
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
// 10 进制
i, _ := strconv.ParseInt("42", 10, 64)
fmt.Println(i) // 42
// 16 进制
i, _ = strconv.ParseInt("2a", 16, 64)
fmt.Println(i) // 42
// 自动检测
i, _ = strconv.ParseInt("0x2a", 0, 64)
fmt.Println(i) // 42
// 负数
i, _ = strconv.ParseInt("-42", 10, 64)
fmt.Println(i) // -42
}
ParseUint
func ParseUint(s string, base int, bitSize int) (uint64, error)
功能: 将字符串转换为无符号整数。
参数:
s string- 要转换的字符串base int- 进制(2-36,0 表示自动检测)bitSize int- 目标类型大小(0、8、16、32、64)
返回值:
uint64- 无符号整数值error- 错误
注意:
- 不接受负号
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
u, _ := strconv.ParseUint("42", 10, 64)
fmt.Println(u) // 42
u, _ = strconv.ParseUint("2a", 16, 64)
fmt.Println(u) // 42
// 负数会报错
_, err := strconv.ParseUint("-42", 10, 64)
fmt.Println("错误:", err) // invalid syntax
}
Q
Quote
func Quote(s string) string
功能: 将字符串转换为双引号 Go 字符串字面量。
参数:
s string- 要引用的字符串
返回值:
string- 引用后的字符串
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
q := strconv.Quote("Hello, 世界")
fmt.Println(q) // "Hello, 世界"
q = strconv.Quote("Hello\nWorld")
fmt.Println(q) // "Hello\nWorld"
}
QuoteRune
func QuoteRune(r rune) string
功能: 将 rune 转换为单引号 Go 字符字面量。
参数:
r rune- 要引用的字符
返回值:
string- 引用后的字符
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
q := strconv.QuoteRune('A')
fmt.Println(q) // 'A'
q = strconv.QuoteRune('世')
fmt.Println(q) // '世'
}
QuoteRuneToASCII
func QuoteRuneToASCII(r rune) string
功能: 将 rune 转换为 ASCII 单引号字面量(非 ASCII 使用 \u 转义)。
参数:
r rune- 要引用的字符
返回值:
string- ASCII 引用后的字符
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
q := strconv.QuoteRuneToASCII('A')
fmt.Println(q) // 'A'
q = strconv.QuoteRuneToASCII('世')
fmt.Println(q) // '\u4e16'
}
QuoteRuneToGraphic
func QuoteRuneToGraphic(r rune) string
功能: 将 rune 转换为可打印单引号字面量。
参数:
r rune- 要引用的字符
返回值:
string- 可打印引用后的字符
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
q := strconv.QuoteRuneToGraphic('A')
fmt.Println(q) // 'A'
}
QuoteToASCII
func QuoteToASCII(s string) string
功能: 将字符串转换为 ASCII 双引号字面量(非 ASCII 使用 \u 转义)。
参数:
s string- 要引用的字符串
返回值:
string- ASCII 引用后的字符串
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
q := strconv.QuoteToASCII("Hello, 世界")
fmt.Println(q) // "Hello, \u4e16\u754c"
}
QuoteToGraphic
func QuoteToGraphic(s string) string
功能: 将字符串转换为可打印双引号字面量。
参数:
s string- 要引用的字符串
返回值:
string- 可打印引用后的字符串
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
q := strconv.QuoteToGraphic("Hello")
fmt.Println(q) // "Hello"
}
QuotedPrefix
func QuotedPrefix(s string) (string, error)
功能: 从字符串中提取第一个引号引用的前缀。
参数:
s string- 包含引用字符串的文本
返回值:
string- 引用的前缀error- 错误
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
s := `"hello" world`
prefix, err := strconv.QuotedPrefix(s)
if err != nil {
fmt.Println("错误:", err)
return
}
fmt.Println(prefix) // "hello"
}
U
Unquote
func Unquote(s string) (string, error)
功能: 将引用的字符串字面量转换回原始字符串。
参数:
s string- 要反引用的字符串
返回值:
string- 原始字符串error- 错误
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
s, err := strconv.Unquote(`"Hello\nWorld"`)
if err != nil {
fmt.Println("错误:", err)
return
}
fmt.Println(s) // Hello
// World
}
UnquoteChar
func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error)
功能: 从字符串中反引用第一个字符。
参数:
s string- 要反引用的字符串quote byte- 引用字符(‘“’ 或 ‘'’)
返回值:
value rune- 反引用后的字符multibyte bool- 是否多字节字符tail string- 剩余字符串error- 错误
示例:
package main
import (
"fmt"
"strconv"
)
func main() {
value, multibyte, tail, err := strconv.UnquoteChar(`"Hello`, '"')
if err != nil {
fmt.Println("错误:", err)
return
}
fmt.Printf("字符:%c, 多字节:%v, 剩余:%s\n", value, multibyte, tail)
}
典型示例
示例 1:字符串转整数
package main
import (
"fmt"
"strconv"
)
func main() {
// Atoi(10 进制)
i, _ := strconv.Atoi("-42")
fmt.Println(i) // -42
// ParseInt(指定进制)
i64, _ := strconv.ParseInt("2a", 16, 64)
fmt.Println(i64) // 42
// ParseInt(自动检测)
i64, _ = strconv.ParseInt("0x2a", 0, 64)
fmt.Println(i64) // 42
// ParseUint
u, _ := strconv.ParseUint("42", 10, 64)
fmt.Println(u) // 42
}
运行结果:
-42
42
42
42
示例 2:整数转字符串
package main
import (
"fmt"
"strconv"
)
func main() {
// Itoa(10 进制)
s := strconv.Itoa(-42)
fmt.Println(s) // -42
// FormatInt(指定进制)
s = strconv.FormatInt(42, 2)
fmt.Println(s) // 101010
s = strconv.FormatInt(42, 16)
fmt.Println(s) // 2a
// FormatUint
s = strconv.FormatUint(42, 16)
fmt.Println(s) // 2a
}
运行结果:
-42
101010
2a
2a
示例 3:字符串转浮点数
package main
import (
"fmt"
"strconv"
)
func main() {
// ParseFloat
f, _ := strconv.ParseFloat("3.1415", 64)
fmt.Println(f) // 3.1415
// float32
f32, _ := strconv.ParseFloat("3.14", 32)
fmt.Println(float32(f32)) // 3.14
// 科学计数法
f, _ = strconv.ParseFloat("1.23e-4", 64)
fmt.Println(f) // 0.000123
}
运行结果:
3.1415
3.14
0.000123
示例 4:浮点数转字符串
package main
import (
"fmt"
"strconv"
)
func main() {
pi := 3.1415926535
// 定点表示
fmt.Println(strconv.FormatFloat(pi, 'f', 2, 64)) // 3.14
// 科学计数法
fmt.Println(strconv.FormatFloat(pi, 'e', 2, 64)) // 3.14e+00
fmt.Println(strconv.FormatFloat(pi, 'E', 2, 64)) // 3.14E+00
// 自动选择
fmt.Println(strconv.FormatFloat(pi, 'g', -1, 64)) // 3.1415926535
}
运行结果:
3.14
3.14e+00
3.14E+00
3.1415926535
示例 5:布尔值转换
package main
import (
"fmt"
"strconv"
)
func main() {
// 字符串转布尔
b, _ := strconv.ParseBool("true")
fmt.Println(b) // true
b, _ = strconv.ParseBool("1")
fmt.Println(b) // true
b, _ = strconv.ParseBool("FALSE")
fmt.Println(b) // false
// 布尔转字符串
fmt.Println(strconv.FormatBool(true)) // true
fmt.Println(strconv.FormatBool(false)) // false
}
运行结果:
true
true
false
true
false
示例 6:字符串引用和反引用
package main
import (
"fmt"
"strconv"
)
func main() {
// Quote
q := strconv.Quote("Hello\nWorld")
fmt.Println(q) // "Hello\nWorld"
// Unquote
s, _ := strconv.Unquote(`"Hello\nWorld"`)
fmt.Println(s) // Hello
// World
// QuoteToASCII
q = strconv.QuoteToASCII("世界")
fmt.Println(q) // "\u4e16\u754c"
}
运行结果:
"Hello\nWorld"
Hello
World
"\u4e16\u754c"
示例 7:Append 系列函数
package main
import (
"fmt"
"strconv"
)
func main() {
// AppendBool
dst := strconv.AppendBool([]byte("bool:"), true)
fmt.Println(string(dst)) // bool:true
// AppendInt
dst = strconv.AppendInt([]byte("int:"), 42, 10)
fmt.Println(string(dst)) // int:42
// AppendFloat
dst = strconv.AppendFloat([]byte("float:"), 3.14, 'f', 2, 64)
fmt.Println(string(dst)) // float:3.14
// AppendUint
dst = strconv.AppendUint([]byte("uint:"), 42, 16)
fmt.Println(string(dst)) // uint:2a
}
运行结果:
bool:true
int:42
float:3.14
uint:2a
示例 8:错误处理
package main
import (
"errors"
"fmt"
"strconv"
)
func main() {
// 语法错误
_, err := strconv.ParseInt("abc", 10, 64)
if err != nil {
var numErr *strconv.NumError
if errors.As(err, &numErr) {
fmt.Printf("函数:%s\n", numErr.Func)
fmt.Printf("输入:%s\n", numErr.Num)
fmt.Printf("错误类型:%v\n", numErr.Err)
}
}
// 范围错误
_, err = strconv.ParseInt("9999999999999999999999", 10, 32)
if err != nil {
fmt.Println("范围错误:", err)
}
}
运行结果:
函数:ParseInt
输入:abc
错误类型:invalid syntax
范围错误:value out of range
最佳实践
1. 选择合适的转换函数
// ✅ 推荐:简单 10 进制转换
i, _ := strconv.Atoi("42")
s := strconv.Itoa(42)
// ✅ 推荐:需要指定进制
i, _ := strconv.ParseInt("2a", 16, 64)
s := strconv.FormatInt(42, 16)
2. 使用 Append 系列提高性能
// ✅ 推荐:避免内存分配
dst := make([]byte, 0, 64)
dst = strconv.AppendInt(dst, 42, 10)
dst = strconv.AppendBool(dst, true)
result := string(dst)
// ❌ 不推荐:多次内存分配
s := strconv.Itoa(42) + strconv.FormatBool(true)
3. 正确处理错误
// ✅ 推荐:检查错误
i, err := strconv.Atoi(s)
if err != nil {
// 处理错误
return
}
// ❌ 不推荐:忽略错误
i, _ := strconv.Atoi(s) // 可能得到 0
4. 使用合适的 bitSize
// ✅ 推荐:指定正确的位大小
f32, _ := strconv.ParseFloat("3.14", 32)
f64, _ := strconv.ParseFloat("3.14", 64)
// ✅ 转换到更小的类型
i64, _ := strconv.ParseInt("42", 10, 32)
i32 := int32(i64)
5. 使用 base=0 自动检测进制
// ✅ 推荐:自动检测
i, _ := strconv.ParseInt("0x2a", 0, 64) // 16 进制
i, _ = strconv.ParseInt("042", 0, 64) // 8 进制
i, _ = strconv.ParseInt("42", 0, 64) // 10 进制
与其他包配合
与 fmt 包配合
package main
import (
"fmt"
"strconv"
)
func main() {
// fmt.Sprintf vs strconv
s1 := fmt.Sprintf("%d", 42)
s2 := strconv.Itoa(42) // 更快
// fmt.Sprintf vs strconv.FormatFloat
s1 = fmt.Sprintf("%.2f", 3.1415)
s2 = strconv.FormatFloat(3.1415, 'f', 2, 64) // 更快
}
与 bytes 包配合
package main
import (
"bytes"
"fmt"
"strconv"
)
func main() {
// 使用 Append 系列
buf := make([]byte, 0, 64)
buf = strconv.AppendInt(buf, 42, 10)
buf = append(buf, ' ')
buf = strconv.AppendBool(buf, true)
fmt.Println(string(buf)) // 42 true
// 使用 bytes.Buffer
var buffer bytes.Buffer
buffer.WriteString("int:")
buffer.WriteString(strconv.Itoa(42))
fmt.Println(buffer.String())
}
注意事项
限制
-
进制范围:
- FormatInt、FormatUint:base 必须在 2-36 之间
- ParseInt、ParseUint:base 必须是 0 或 2-36
-
精度限制:
- float32:约 7 位有效数字
- float64:约 15 位有效数字
-
范围限制:
- int8:-128 到 127
- int16:-32768 到 32767
- int32:-2147483648 到 2147483647
- int64:-9223372036854775808 到 9223372036854775807
-
ParseBool 接受的字符串:
- 真:1、t、T、true、True、TRUE
- 假:0、f、F、false、False、FALSE
- 其他字符串返回错误
使用建议
-
性能考虑:
// ✅ 推荐:strconv 比 fmt 快 s := strconv.Itoa(42) // ❌ 不推荐:fmt 较慢 s := fmt.Sprintf("%d", 42) -
避免溢出:
// ✅ 推荐:检查范围 i64, err := strconv.ParseInt(s, 10, 32) if err != nil { // 处理错误 } i32 := int32(i64) // ❌ 不推荐:可能溢出 i, _ := strconv.Atoi(s) // 可能是 64 位 -
浮点数精度:
// ✅ 推荐:使用 -1 精度 s := strconv.FormatFloat(3.14, 'f', -1, 64) // ❌ 不推荐:可能丢失精度 s := strconv.FormatFloat(3.14, 'f', 2, 64) // 3.14
快速参考
函数速查表
| 函数 | 功能 | 方向 |
|---|---|---|
Atoi | 字符串转 int | 字符串 → 数字 |
Itoa | int 转字符串 | 数字 → 字符串 |
ParseInt | 字符串转 int64 | 字符串 → 数字 |
ParseUint | 字符串转 uint64 | 字符串 → 数字 |
ParseFloat | 字符串转 float64 | 字符串 → 数字 |
ParseBool | 字符串转 bool | 字符串 → 数字 |
ParseComplex | 字符串转 complex128 | 字符串 → 数字 |
FormatInt | int64 转字符串 | 数字 → 字符串 |
FormatUint | uint64 转字符串 | 数字 → 字符串 |
FormatFloat | float64 转字符串 | 数字 → 字符串 |
FormatBool | bool 转字符串 | 数字 → 字符串 |
FormatComplex | complex128 转字符串 | 数字 → 字符串 |
AppendInt | 追加 int64 到 []byte | 数字 → 字节 |
AppendUint | 追加 uint64 到 []byte | 数字 → 字节 |
AppendFloat | 追加 float64 到 []byte | 数字 → 字节 |
AppendBool | 追加 bool 到 []byte | 数字 → 字节 |
Quote | 引用字符串 | 字符串 → 字符串 |
Unquote | 反引用字符串 | 字符串 → 字符串 |
FormatFloat 格式说明
| 格式 | 示例 | 描述 |
|---|---|---|
'b' | -1.234p+0 | 二进制指数 |
'e' | -1.234e+00 | 十进制指数(小写) |
'E' | -1.234E+00 | 十进制指数(大写) |
'f' | -1.234000 | 定点表示 |
'g' | -1.234 | 自动选择(小写) |
'G' | -1.234 | 自动选择(大写) |
ParseInt bitSize 对照
| bitSize | 目标类型 | 范围 |
|---|---|---|
| 0 | int | 系统相关 |
| 8 | int8 | -128 到 127 |
| 16 | int16 | -32768 到 32767 |
| 32 | int32 | -2147483648 到 2147483647 |
| 64 | int64 | -9223372036854775808 到 9223372036854775807 |
常见模式
// 1. 字符串转整数
i, _ := strconv.Atoi("42")
i64, _ := strconv.ParseInt("42", 10, 64)
// 2. 整数转字符串
s := strconv.Itoa(42)
s = strconv.FormatInt(42, 16) // 16 进制
// 3. 字符串转浮点数
f, _ := strconv.ParseFloat("3.14", 64)
// 4. 浮点数转字符串
s = strconv.FormatFloat(3.14, 'f', 2, 64)
// 5. 字符串转布尔
b, _ := strconv.ParseBool("true")
// 6. 布尔转字符串
s = strconv.FormatBool(true)
// 7. 追加到字节切片
dst = strconv.AppendInt(dst, 42, 10)
dst = strconv.AppendFloat(dst, 3.14, 'f', 2, 64)
// 8. 引用字符串
q := strconv.Quote("Hello")
s, _ := strconv.Unquote(`"Hello"`)
总结
strconv 包是 Go 标准库中用于字符串和基础数据类型转换的核心包。
核心优势:
- ✅ 功能全面(int、uint、float、bool、complex)
- ✅ 性能优秀(比 fmt 包快)
- ✅ Append 系列避免内存分配
- ✅ 错误处理清晰(*NumError 类型)
- ✅ 支持多种进制
重要限制:
- ⚠️ 进制必须在 2-36 之间
- ⚠️ 注意数值范围溢出
- ⚠️ 浮点数精度限制
主要用途:
- 字符串和数字互转
- 格式化数字为字符串
- 解析字符串为数字
- 字符串引用和反引用
- 高效字节切片追加
使用建议:
- 简单 10 进制转换使用 Atoi/Itoa
- 需要指定进制使用 ParseInt/FormatInt
- 高性能场景使用 Append 系列
- 始终检查错误
- 使用合适的 bitSize 避免溢出
性能提示:
- strconv 比 fmt.Sprintf 快 3-5 倍
- Append 系列比字符串拼接更高效
- 批量转换时预分配字节切片