- 必须显式转换:
所有类型转换都需要明确指定目标类型,编译器不会自动转换。 - 严格类型安全:
转换只能在兼容类型之间进行(如数值类型之间、基础类型与其别名之间)。 - 语法格式:
newValue := TargetType(oldValue)
在Go语言中,所有类型转换必须显式声明,且只能在兼容类型之间进行。以下是Go语言中常见的类型转换示例,涵盖基本类型、自定义类型、指针、接口等场景:
一、基本类型转换
1. 数值类型互转
// int → float
a := 10
b := float64(a) // int → float64
// float → int (截断小数)
c := 3.14
d := int(c) // float64 → int (值为3)
// int不同位数转换
e := int32(1000)
f := int64(e) // int32 → int64
// 注意溢出
big := 50000
small := int8(big) // 溢出(int8范围: -128~127)
2. 字符串与数值
// string ↔ []byte
s := "hello"
bytes := []byte(s) // string → []byte
s2 := string(bytes) // []byte → string
// strconv包实现字符串与数值转换
import "strconv"
numStr := "123"
num, _ := strconv.Atoi(numStr) // string → int
str := strconv.Itoa(456) // int → string
// 解析浮点数
floatStr := "3.14"
f, _ := strconv.ParseFloat(floatStr, 64) // string → float64
二、自定义类型转换
1. 基础类型与别名
type Celsius float64
type Fahrenheit float64
var tempC Celsius = 20.0
tempF := Fahrenheit(tempC * 9/5 + 32) // 自定义类型需显式转换
2. 类型断言(接口转换)
var i interface{} = "hello"
// 安全断言
s, ok := i.(string) // 接口 → string
if ok {
fmt.Println(s) // 输出: hello
}
// 非安全断言(panic风险)
n := i.(int) // 触发panic
三、指针类型转换
1. 普通指针转换
x := 10
p := &x // *int
pp := (**int)(&p) // **int
// unsafe.Pointer万能指针(需谨慎)
import "unsafe"
y := 20
pY := unsafe.Pointer(&y)
intPtr := (*int)(pY) // unsafe.Pointer → *int
2. 结构体指针转换
type Person struct{ Name string }
type Student struct{ Name string }
p := &Person{"Alice"}
// 需通过unsafe强制转换(非推荐做法)
s := (*Student)(unsafe.Pointer(p))
四、特殊类型转换
1. 通道类型转换
ch1 := make(chan int)
ch2 := (chan<- int)(ch1) // 双向通道 → 只发送通道
2. 函数签名转换
func greet(s string) { fmt.Println(s) }
var f func(string) = greet // 函数类型匹配
五、类型转换规则总结
转换场景 | 示例 | 注意事项 |
---|---|---|
数值类型互转 | float64(42) | 注意溢出和精度丢失 |
字符串 ↔ 字节切片 | []byte("hello") | 涉及编码问题(UTF-8) |
接口类型断言 | val, ok := x.(string) | 必须检查ok |
自定义类型 ↔ 基础类型 | int(myType) | 需显式声明 |
unsafe.Pointer强制转换 | (*int)(unsafe.Pointer(&x)) | 绕过类型系统,高风险操作 |
关键注意事项
- 所有转换必须显式声明,Go没有隐式转换。
- 非常量数值转换时,编译器不会检查溢出。
- unsafe操作会绕过类型系统,需谨慎使用。
- 类型断言是接口类型转换的核心机制。