Golang strconv字符串与数字转换实践
在Golang开发过程中,字符串和基本数据类型(尤其是数字类型)之间的转换是非常常见的操作。标准库中的strconv包提供了一系列用于字符串和其他基本数据类型之间转换的函数,熟练掌握这些函数的使用,能让我们在处理用户输入、配置文件解析、网络数据传输等场景时更加得心应手。
strconv包的核心转换函数
strconv包针对不同的数字类型提供了对应的转换函数,主要分为两类:将字符串转为数字的函数,以及将数字转为字符串的函数。下面我们分别介绍常用的函数及其使用场景。
字符串转数字
将字符串转换为数字时,常用的函数有Atoi和Parse系列函数。其中Atoi是ParseInt的便捷版本,专门用于将字符串转换为int类型,而Parse系列函数可以支持更多数字类型和进制转换。
package main
import (
"fmt"
"strconv"
)
func main() {
// 使用Atoi将字符串转为int类型
str1 := "123"
num1, err1 := strconv.Atoi(str1)
if err1 != nil {
fmt.Println("转换失败:", err1)
} else {
fmt.Printf("字符串%s转为int结果: %d, 类型: %T\n", str1, num1, num1)
}
// 使用ParseInt转换不同进制的字符串为int64
str2 := "1010"
// 参数分别为:待转换字符串、进制(2表示二进制)、位数(0表示根据字符串自动判断,通常返回int64)
num2, err2 := strconv.ParseInt(str2, 2, 64)
if err2 != nil {
fmt.Println("转换失败:", err2)
} else {
fmt.Printf("二进制字符串%s转为int64结果: %d\n", str2, num2)
}
// 使用ParseFloat转换字符串为float64
str3 := "3.1415926"
num3, err3 := strconv.ParseFloat(str3, 64)
if err3 != nil {
fmt.Println("转换失败:", err3)
} else {
fmt.Printf("字符串%s转为float64结果: %.2f, 类型: %T\n", str3, num3, num3)
}
}上面的代码演示了三种常见的字符串转数字场景:Atoi处理十进制的int转换,ParseInt可以指定进制处理不同进制的字符串,ParseFloat处理浮点数字符串的转换。需要注意的是,这些转换函数都会返回两个值,第一个是转换后的结果,第二个是错误信息,实际开发中一定要处理错误,避免不合法的字符串导致程序异常。
数字转字符串
将数字转换为字符串时,常用的函数有Itoa和Format系列函数。Itoa是FormatInt的便捷版本,用于将int类型转换为十进制字符串,Format系列函数可以支持更多数字类型和格式控制。
package main
import (
"fmt"
"strconv"
)
func main() {
// 使用Itoa将int转为字符串
num1 := 456
str1 := strconv.Itoa(num1)
fmt.Printf("int类型%d转为字符串结果: %s, 类型: %T\n", num1, str1, str1)
// 使用FormatInt将int64转为不同进制的字符串
var num2 int64 = 255
// 转为二进制字符串
str2 := strconv.FormatInt(num2, 2)
fmt.Printf("int64类型%d转为二进制字符串: %s\n", num2, str2)
// 转为十六进制字符串
str3 := strconv.FormatInt(num2, 16)
fmt.Printf("int64类型%d转为十六进制字符串: %s\n", num2, str3)
// 使用FormatFloat将float64转为字符串
num3 := 3.1415926
// 参数分别为:待转换数字、格式('f'表示十进制表示)、小数位数(-1表示使用最少的小数位数)、位数(64表示float64)
str4 := strconv.FormatFloat(num3, 'f', 2, 64)
fmt.Printf("float64类型%.7f转为保留2位小数的字符串: %s\n", num3, str4)
}代码中展示了数字转字符串的常用方式:Itoa处理int到十进制字符串的快速转换,FormatInt可以指定进制输出不同进制的数字字符串,FormatFloat可以通过格式参数控制浮点数的输出形式,比如保留小数位数、使用科学计数法表示等。
常见使用注意事项
在实际使用strconv包的函数时,有几个点需要特别注意,避免踩坑:
- 转换函数返回的错误信息一定要处理,比如字符串中包含非数字字符、数字超出目标类型的范围时,都会返回错误,不处理错误直接使用转换结果可能导致程序崩溃。
- ParseInt和FormatInt默认处理的都是int64类型,如果需要其他整数类型,转换后需要做类型断言或者显式类型转换,同时注意范围问题。
- FormatFloat的格式参数有多个可选值,比如'f'是普通十进制,'e'是科学计数法,'g'会根据数字大小自动选择'f'或'e'格式,选择时需要结合实际需求。
- 如果字符串内容是布尔值,还可以使用ParseBool和FormatBool函数进行布尔值和字符串的转换,比如strconv.ParseBool("true")会返回布尔值true。
实际场景示例
下面我们通过一个简单的配置文件解析场景,看看strconv包的实际应用。假设我们从配置文件中读取到端口号和超时时间的配置项,都是字符串类型,需要转换为对应的数字类型使用:
package main
import (
"fmt"
"strconv"
)
// 模拟从配置文件读取到的配置项,实际场景中可能来自文件、环境变量等
var config = map[string]string{
"port": "8080",
"timeout": "30",
"rate": "0.85",
}
func main() {
// 转换端口号,要求是整数
portStr := config["port"]
port, err := strconv.Atoi(portStr)
if err != nil {
fmt.Printf("端口配置%s转换失败: %v,使用默认端口8080\n", portStr, err)
port = 8080
}
fmt.Printf("服务端口: %d\n", port)
// 转换超时时间,支持不同进制(比如配置可能写0x1e表示30秒)
timeoutStr := config["timeout"]
// 先尝试按十进制转换,失败再尝试按十六进制转换
timeout, err := strconv.ParseInt(timeoutStr, 10, 64)
if err != nil {
// 十进制转换失败,尝试十六进制
timeout, err = strconv.ParseInt(timeoutStr, 16, 64)
if err != nil {
fmt.Printf("超时时间配置%s转换失败: %v,使用默认超时30秒\n", timeoutStr, err)
timeout = 30
}
}
fmt.Printf("请求超时时间: %d秒\n", timeout)
// 转换比率,浮点数
rateStr := config["rate"]
rate, err := strconv.ParseFloat(rateStr, 64)
if err != nil {
fmt.Printf("比率配置%s转换失败: %v,使用默认比率0.8\n", rateStr, err)
rate = 0.8
}
fmt.Printf("当前比率: %.2f\n", rate)
}这个示例模拟了实际开发中解析配置的常见流程,针对不同的配置项选择合适的转换函数,并且都做了错误处理,当配置内容不合法时使用默认值,避免程序因为配置问题直接崩溃。可以看到strconv包的函数在基础数据转换场景下的实用性很强,几乎覆盖了大部分字符串和数字互转的需求。