主要区别
特性 | 类型转换 | 类型断言 |
---|---|---|
用途 | 在兼容的类型之间转换值。 | 从接口类型提取实际存储的具体类型的值。 |
适用范围 | 两种可以相互转换的类型。 | 接口类型和具体类型之间的关系。 |
目标类型 | 通常是基本类型或显式转换规则类型。 | 任何具体类型( |
是否改变值 | 可能改变值的表示方式(如截断、精度丢失)。 | 不改变值,只确认实际存储的类型。 |
运行时安全性 | 不安全转换会在编译时报错。 | 错误断言在运行时会 panic(除非使用 |
示例 | var b float64 = | userID := |
类型转换
基本数据类型转换
将整数转换为浮点数
var i int = 42 var f float64 = float64(i) fmt.Println(f) // 42.0
将浮点数转换为整数
- 浮点数小数点之后的数字直接丢弃,不会进行四舍五入
var f2 float64 = 3.14 var i2 int = int(f2) fmt.Println(i2) // 3
整型转字符串
var i3 int = 123 var s string = fmt.Sprintf("%d", i3) fmt.Println(s) // "123"
字符串转整型
var s2 string = "456" var i4, _ = fmt.Sscanf(s2, "%d", &i3) fmt.Println(i4) // 456
接口类型转换
package main import "fmt" type Animal interface { Speak() string } type Dog struct{} func (d Dog) Speak() string { return "Woof" } func main() { var a Animal = Dog{} // 类型断言 d := a.(Dog) fmt.Println(d.Speak()) // Woof }
指针类型转换
package main import "fmt" type A struct { Name string } type B struct { Age int } func main() { a := &A{Name: "John"} b := (*B)(unsafe.Pointer(a)) // 不建议这样使用,需导入unsafe包,谨慎使用 fmt.Println(b) // 在不兼容类型时,可能会导致不可预测的行为 }
类型断言
定义
类型断言用于 从接口类型提取具体类型的值。它的作用是确认接口类型的变量内部实际存储的值是什么类型。
使用场景
类型断言用于从接口类型(如 interface{})中还原其存储的具体值和类型,比如:
- 从一个通用的 interface{} 提取出具体类型。
- 检查一个接口是否实现了某种接口。
安全类型断言(避免 panic):
package main import "fmt" func main() { var i interface{} = "hello" // 使用 comma-ok 模式 if s, ok := i.(string); ok { fmt.Println("类型是 string,值是:", s) } else { fmt.Println("不是 string 类型") } }