Go中只有类型转换(conversion)和类型断言(assertion):类型转换用于兼容具体类型间显式转换(如int→int64),类型断言用于从接口提取具体类型(如interface{}→string),二者不可混淆。
Go 里没有“类型转换”这个说法,只有类型断言和类型转换(conversion)
go 不支持隐式类型转换,所有跨类型的值操作都必须显式声明意图。关键区别在于:type conversion 是相同底层类型的值重新解释(如 int → int64),而 type assertion 是从接口中提取具体类型(如 interface{} → string)。混淆这两者是新手最常卡住的地方。
-
int(3.14)合法 —— 因为int和float64底层不兼容,这行代码会编译失败;正确写法是int(math.Floor(3.14))或先转int64再转int -
string(65)得到"A",但string([]byte{'h','e','l','l','o'})才能得到"hello";直接string([]byte)是合法转换,而string([]rune)也是,但string([]int)不行 - 从
interface{}拿值时,v.(string)是断言,失败 panic;更安全用双变量形式:s, ok := v.(string)
字符串和数字互转必须用 strconv 包
别试图用 int("123") 或 string(123),它们要么编译失败,要么得到意外结果(比如 string(123) 是字符 "{")。所有字符串和基本数值的双向转换都得走 strconv。
-
strconv.Atoi("42")→(42, nil);注意它只处理int(平台相关,32 或 64 位),要明确宽度用strconv.ParseInt("42", 10, 64) -
strconv.Itoa(42)最快,但仅限int;其他类型用strconv.FormatInt(int64(x), 10)、strconv.FormatFloat(3.14, 'f', -1, 64) -
strconv.Unquote(`"hello"`)可解带引号的字符串字面量,strconv.Quote("hello")加上双引号并转义,适合生成 Go 字符串字面量
切片和数组之间不能直接转换,但 []T 和 []U 在底层一致时可 unsafe 转(慎用)
例如 []byte 和 []uint8 底层完全一样,可以安全转换:bytes := []byte("hi"); uints := ([]uint8)(bytes)。但 []byte 和 []int8 虽然都是 1 字节,Go 不允许直接转 —— 因为语义不同,需通过 unsafe.Slice 或 reflect.SliceHeader(Go 1.17+ 推荐前者)。
- 安全替代方案:用
bytes.Equal比较[]byte和[]uint8,或用copy(dst, src)显式复制 - 若真需 zero-copy 转换(如高性能序列化),用
unsafe.Slice((*T)(unsafe.Pointer(&src[0])), len(src)),但必须确保T和原切片元素底层内存布局一致,且长度不越界 -
unsafe操作在 CGO 环境或某些静态分析工具下会被拦截,上线前务必测试
JSON 和结构体互转本质是编组/解组,不是类型转换
把 map[string]interface{} 直接强制转成自定义 struct 会 panic。必须用 json.Unmarshal 解析字节流,或用 mapstructure 等第三方库做 map → struct 映射。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
-
json.Marshal(struct{X int}{42})→[]byte(`{"X":42}`);反过来必须提供地址:json.Unmarshal(b, &v),传值会静默失败 - 字段必须是导出的(大写字母开头),否则
json包看不到;可用json:"x,omitempty"控制键名和空值省略 - 时间字段常用
time.Time,但 JSON 默认输出 RFC3339 字符串;若后端用 Unix 时间戳,需自定义UnmarshalJSON方法
真正麻烦的从来不是语法怎么写,而是搞不清某个操作到底是 conversion、assertion 还是编组 —— 看报错信息里的关键词:cannot convert 是 conversion 错误,invalid type assertion 是 interface 断言问题,json: cannot unmarshal 就该去查数据结构匹配度。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










