Go语言禁止隐式类型转换,所有转换必须显式写出:数值类型用T(x)但行为各异(如float64→int截断小数、uint↔int按位复制);string与[]byte互转有内存差异(前者复用底层数组,后者必拷贝);字符串与数字转换须用strconv包;接口还原需类型断言而非T(x)。

Go 语言不允许隐式类型转换,所有转换都必须显式写出,否则编译直接报错。这不是限制,而是防止意外截断、精度丢失或语义混淆的设计选择。
数值类型之间怎么用 t(x) 转换
同类数值类型(如 int ↔ int64、float64 → int)支持直接用 T(x) 语法,但行为差异明显:
-
int64→int:编译器不检查溢出;运行时若值超出目标范围,结果未定义(通常是高位截断) -
float64→int:直接截断小数部分,不是四舍五入;-3.9转成int是-3 -
uint↔int:按位复制;int(-1)→uint会得到极大正数(如0xffffffff) - 自定义类型(哪怕底层是
int)和它的底层类型互转也必须显式写MyType(x)或int(myVar),编译器不认为它们“相等”
string 和 []byte 互转的内存行为差异
它们底层都是字节序列,所以允许直接转换,但语义和内存行为完全不同:
-
string([]byte):不分配新内存,复用原底层数组(只读视图);后续修改原[]byte不影响已转出的string -
[]byte(string):一定分配新底层数组,原字符串内容被拷贝一份;即使只是临时转一下再丢掉,也会有一次分配和复制 - 大量重复转换会造成 GC 压力,尤其在循环里——能缓存就缓存,别每次都转
- 别以为 “
string和[]byte可以自由转” 就忽略开销;标准库从不为省一次拷贝用unsafe做零拷贝反向转换
字符串和数字之间为什么不能用 t(x)
这类跨类转换不能用 T(x),因为涉及解析逻辑和错误处理,必须走 strconv 包:
立即学习“go语言免费学习笔记(深入)”;
-
string→int:用strconv.Atoi()(十进制)或strconv.ParseInt(s, 10, 64)(可指定进制和位宽) -
int→string:首选strconv.Itoa()(快且简洁),或strconv.FormatInt(int64, 10) -
float64→string:用strconv.FormatFloat(f, 'g', -1, 64),第三个参数控制精度,-1表示自动选择最短表示 - 所有
Parse*函数都返回(value, error);忽略error是常见 panic 来源
接口值还原为具体类型要用类型断言,不是 t(x)
当变量是 interface{} 或某个接口类型,需要还原为具体类型时,不能用 T(x),得用类型断言:
- 暴力断言:
s := i.(string)—— 如果i不是string,运行时 panic - 安全断言:
s, ok := i.(string)——ok为false时不 panic,可做分支处理 - 多个类型判断用
type switch,比一连串if s, ok :=更清晰 - 只有接口值持有了具体类型的实例,断言才可能成功;空接口
nil断言任何类型都会失败
最容易被忽略的是:类型转换后值的生命周期是否还受控。比如把局部 slice 的地址转成 string,slice 被回收后 string 仍指向那片内存——Go 编译器会阻止这种逃逸,但用 unsafe 强行绕过时,没人替你保命。


















