一、Go 类型转换的核心原则
Go 是强类型语言,几乎所有类型转换都必须显式写出来
不存在 Java 那种「自动提升 + 隐式转换」,如果不写,编译器就直接报错。
二、Go 的基本类型转换语法
通用写法
Go
T(v)
-
T:目标类型 -
v:原变量
示例
java
var a int = 10
var b int64 = int64(a)
var c float64 = float64(a)
不能这样写:
Go
var b int64 = a // 编译错误
三、数值类型之间的转换
int / int32 / int64
Go
var a int32 = 100
var b int64 = int64(a)
var c int = int(b)
int ↔ float
Go
var a int = 3
var b float64 = float64(a) // 3.0
var c float64 = 3.9
var d int = int(c) // 3
注意:上面int转float,会直接截断,不是四舍五入。
四、字符串相关的转换
错误示例(Java 思维)
Go
s := string(123) // ❌
结果是 Unicode 字符 ,不是 "123"
数字 ↔ 字符串(正确姿势)
int → string
Go
import "strconv"
s := strconv.Itoa(123) // "123"
string → int
Go
i, err := strconv.Atoi("123")
string ↔ float
Go
f, _ := strconv.ParseFloat("3.14", 64)
s := strconv.FormatFloat(f, 'f', 2, 64) // "3.14"
string ↔ []byte / []rune
Go
s := "你好"
b := []byte(s) // UTF-8 字节
r := []rune(s) // Unicode 字符
fmt.Println(len(b)) // 6
fmt.Println(len(r)) // 2
五、类型断言
interface{} 转具体类型
基本用法
Go
var v interface{} = 100
i := v.(int)
如果类型不对,直接 panic
安全写法(强烈推荐)
Go
i, ok := v.(int)
if ok {
fmt.Println(i)
}
switch 断言(Go 风格)
Go
func printType(v interface{}) {
switch t := v.(type) {
case int:
fmt.Println("int", t)
case string:
fmt.Println("string", t)
default:
fmt.Println("unknown")
}
}
六、类型转换 vs 类型断言
| 对比点 | 类型转换 | 类型断言 |
|---|---|---|
| 用途 | 基本类型 | interface |
| 语法 | T(v) | v.(T) |
| 是否编译期检查 | 是 | 否 |
| 错误表现 | 编译错误 | panic / ok=false |
七、自定义类型的转换
定义新类型
Go
type MyInt int
不能直接用
Go
var a int = 10
var b MyInt = a // 编译错误
必须显式转换
Go
var b MyInt = MyInt(a)
即使底层类型一样,也当成 不同类型
八、struct 之间能不能转换
struct 之间能不能转换?
普通 struct 不行
Go
type A struct {
X int
}
type B struct {
X int
}
Go
var a A
var b B = a // ❌
只有在 字段完全一致 + 类型别名 情况下才行
Go
type B = A
九、Go vs Java 类型转换对比
| 场景 | Go | Java |
|---|---|---|
| int → long | 必须写 int64(x) | 自动 |
| float → int | 强制转换,截断 | 强制转换 |
| 数字 → string | strconv | String.valueOf |
| interface → 实体 | 断言 | instanceof + cast |
| 自定义类型 | 必须显式 | 多态/继承 |