Go 语言基本数据类型与字符串相互转换详解
Go 语言的类型系统要求严格的显式转换,不支持自动隐式转换。本文详细介绍基本数据类型(int、float、bool)之间的转换规则、溢出检查机制,以及通过标准库 strconv 和 fmt 实现基本类型与字符串相互转换的具体方法与代码示例。
基本数据类型的显式转换
在 Go 语言中,不同类型的变量之间赋值必须通过显式转换来完成,编译器不允许隐式转换。这有助于减少因精度丢失或数据范围不符导致的潜在 bug。
第 1 步:基础转换语法与使用
目的:了解将值从一种类型转换为另一种类型的基本语法规则。
语法:表达式格式为 T(v),其中 T 表示目标类型(如 int32, float64),v 表示需要转换的源值。
注意:在不考虑数值溢出的情况下,类型转换通常不会改变数值的大小,仅改变其在内存中的表示方式或位数。
package main
import "fmt"
func main() {
var i int8 = 100
// 将 int8 显式转换为 int32
var n int32 = int32(i)
fmt.Println(i, n) // 输出: 100 100
}
第 2 步:处理不同整数类型间的算术运算
目的:解决混合类型参与运算时的编译错误。
Go 不支持不同整数类型(如 int32 和 int16)之间的隐式转换。如果直接对不同大小的整数进行加减运算并赋值,编译器会报错。此时需要将其中一个操作数显式转换为目标类型。
package main
import "fmt"
func main() {
var n1 int32 = 30
var n2 int16
var n3 int64
// 错误写法:n1 + 2 仍为 int32 类型,无法直接赋给 int16 类型的 n2
// n2 = n1 + 2
// 正确做法:先将 n1 转换为 n2 的类型 (int16),再进行加法
n2 = int16(n1) + 2
// 同理,将 n1 转换为 n3 的类型 (int64)
n3 = int64(n1) + 2
fmt.Println(n1, n2, n3) // 输出: 30 32 32
}
第 3 步:理解类型转换中的溢出风险
目的:识别并处理超出目标类型范围时的溢出情况。
当转换后的结果超过目标类型能表示的范围时,会发生溢出。Go 编译器会在编译期静态检查常量是否溢出,但对于变量运行时可能出现的溢出,虽然能通过编译,但结果会遵循二进制补码截断规则,导致非预期的负值或乱码。
package main
import "fmt"
func main() {
var n1 int32 = 12
var n2 int8
var n3 int8
// n1(12) 转为 int8 后加 127,仍在 int8 范围内 (-128 到 127)
n2 = int8(n1) + 127
// 结果为 -124 (计算过程涉及补码溢出截断)
// 尝试加入常量 128 会导致编译错误:constant 128 overflows int8
// n3 = int8(n1) + 128
// 修正方案:调整为未溢出的数值进行测试
n3 = int8(n1) + 120
fmt.Println(n1, n2, n3) // 输出: 12 -117 -124
}
技巧:忽略未使用的导入包
如果在代码中引入了某个包但暂时不使用,为了通过编译且保留引用关系,可以在包名前添加下划线 _。这通常用于初始化该包的副作用(如注册插件)。
import (
_ "fmt" // 忽略直接使用,仅执行 init 逻辑(如果有)
_ "unsafe" // 同理
)
基本数据类型与 string 的互转
Go 语言没有内置的自动字符串与基本类型互转操作符,主要依赖标准库 fmt 和 strconv 进行处理。
第 1 阶段:基本类型转 string
目的:将数字、布尔值等基本类型格式化为字符串。
方法 A:使用 fmt.Sprintf
该方法简单直观,利用格式化字符串返回一个新的 string 类型。
package main
import "fmt"
func main() {
var n int = 10
var n1 float64 = 12.56
var b bool = false
var myChar byte = 'h'
var str string
// %d 格式化整型
str = fmt.Sprintf("%d", n)
fmt.Printf("%T %v\n", str, str) // string 10
// %f 格式化浮点型
str = fmt.Sprintf("%f", n1)
fmt.Printf("%T %v\n", str, str) // string 12.560000
// %t 格式化布尔型
str = fmt.Sprintf("%t", b)
fmt.Printf("%T %q\n", str, str) // string "false"
// %q 格式化字符型(带引号)
str = fmt.Sprintf("%q", myChar)
fmt.Printf("%T %q\n", str, str) // string "'h'"
}
方法 B:使用 strconv 包
strconv 提供了更底层、性能更好的转换函数,适合高频调用场景。
- Bool 转字符串 (
FormatBool)
var b = true
str := strconv.FormatBool(b)
fmt.Printf("%T %q\n", str, str) // string "true"
- Int 转字符串 (
FormatInt)
需要指定进制 base (10 为十进制)。
var num3 int = 99
// 先转为 int64 再传入
str := strconv.FormatInt(int64(num3), 10)
fmt.Printf("%T %q\n", str, str) // string "99"
- Float 转字符串 (
FormatFloat)
参数说明:
- f: 浮点数
- fmt: 格式 ('b', 'e', 'f', 'g')
- prec: 精度
- bitSize: 来源位宽 (32 或 64)
var num4 float64 = 23.456
str := strconv.FormatFloat(float64(num4), 'f', 10, 64)
fmt.Printf("%T %q\n", str, str) // string "23.4560000000"
- Int (10进制) 快速转字符串 (
Itoa)
var num5 int = 4567
str := strconv.Itoa(num5)
fmt.Printf("%T %q\n", str, str) // string "4567"
第 2 阶段:String 转基本数据类型
目的:将文本解析为具体的数值类型。
重要提醒:如果字符串无法被正确解析(例如试图将 "hello" 转为整数),Go 通常会静默失败并返回对应类型的零值(int 为 0, bool 为 false, float 为 0.0),同时伴随一个非空 error。因此务必检查返回值中的 error。
1. String 转 Bool (ParseBool)
支持 "true/TRUE/t/T", "false/FALSE/f/F"。
var str string = "true"
var b bool
var err error
b, err = strconv.ParseBool(str)
if err != nil {
fmt.Println("转换出错:", err)
} else {
fmt.Printf("%T %v\n", b, b) // bool true
}
2. String 转 Int (ParseInt)
返回值固定为 int64。如需其他类型,需手动二次转换。
var str2 string = "123"
var n int64
var n2 int
var err error
// base=10, bitSize=64
n, err = strconv.ParseInt(str2, 10, 64)
if err == nil {
n2 = int(n) // 强制转换为 int
fmt.Printf("%T %v\n", n, n) // int64 123
fmt.Printf("%T %v\n", n2, n2) // int 123
}
3. String 转 Uint (ParseUint)
用法同 ParseInt,返回值为 uint64。
4. String 转 Float (ParseFloat)
返回值固定为 float64。
var str3 string = "123.456"
var f1 float64
var err error
f1, err = strconv.ParseFloat(str3, 64)
if err == nil {
fmt.Printf("%T %v\n", f1, f1) // float64 123.456
}
5. 异常处理案例
当字符串内容与目标类型不匹配时,观察默认行为:
var str4 string = "hello"
var f2 float64
var b2 bool
var err error
// 解析浮点数失败 -> 返回 0
f2, err = strconv.ParseFloat(str4, 64)
fmt.Printf("Float: %v, Error: %v\n", f2, err)
// 解析布尔失败 -> 返回 false
b2, err = strconv.ParseBool(str4)
fmt.Printf("Bool: %v, Error: %v\n", b2, err)
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













