Go 语言类型转换
与 C/Java 不同,Go 没有隐式类型转换:不同类型之间不能直接赋值、比较或参与运算,必须显式写出转换,语法是 T(x),把 x 转换为目标类型 T。数值(整型、浮点、byte、rune)之间转换最常用,字符串与数值互转则要借助 strconv 包。(说明:片段代码需放入 main 函数并补 import 运行)
数值类型互转:T(x)
package main
import "fmt"
func main() {
var i int = 97
f := float64(i) // int -> float64
fmt.Println(f) // 输出:97
var pi float64 = 3.99
n := int(pi) // float64 -> int
fmt.Println(n) // 输出:3
b := byte(i) // int -> byte
fmt.Println(b) // 输出:97
r := rune(20320) // rune 本质是 int32,存 Unicode 码点
fmt.Printf("%c\n", r) // 输出:你
}
byte 是 uint8 的别名、rune 是 int32 的别名,所以它们与整型本质是同一类,可直接互转。
转换截断与溢出注意
浮点转整型是向零截断(直接扔掉小数部分,不是四舍五入);大值转小范围类型会发生溢出回绕,Go 不报错也不抛异常,结果按补码回绕,必须自己小心:
fmt.Println(int(3.9), int(-3.9)) // 输出:3 -3 向零截断
big := 300
small := int8(big) // int8 范围 -128~127,300 超出后回绕
fmt.Println(small) // 输出:44
把数字转字符串要留意:string(65) 得到的是字符 "A"(按码点解释),而不是 "65",想得到数字文本必须用 strconv。
字符串与数值转换:strconv 包
import "strconv"
s := strconv.Itoa(123) // int -> string
fmt.Println(s) // 输出:123
n, err := strconv.Atoi("42") // string -> int,失败时 err 非 nil
fmt.Println(n, err) // 输出:42 <nil>
_, err = strconv.Atoi("abc")
fmt.Println(err) // 输出:strconv.Atoi: parsing "abc": invalid syntax
n64, _ := strconv.ParseInt("ff", 16, 64) // 按进制解析:基数 16
f, _ := strconv.ParseFloat("3.14", 64) // 字符串 -> 浮点
b, _ := strconv.ParseBool("true") // 字符串 -> 布尔
fmt.Println(n64, f, b) // 输出:255 3.14 true
Atoi 是 ParseInt(s, 10, 0) 的简写;ParseXxx 家族转换失败时返回错误而不是 panic,正式代码要检查 err。
断言不是转换
接口值还原成具体类型用的是类型断言 x.(T):它发生在运行期、依赖接口的动态类型,与这里编译期的静态转换 T(x) 是两回事,详见下一篇《Go 类型断言》。
小结:Go 杜绝隐式转换,数值互转直接写 T(x),但要提防截断与溢出;字符串与数值互转用 strconv 包并检查 err;类型断言属于运行期操作,与转换不同。