Go 是一种静态类型的编译型语言,每一个变量在使用时都有明确的类型与之对应。Go 中,关于数据类型,主要有三点容易让人迷惑,分别是类型转换、类型断言和类型选择,下面分别讲解,并给出相应示例。
1.类型转换
Go 中不同类型变量间进行赋值是不允许的,即编译时会出现编译错误。Go 语言崇尚“显式表达,避免隐含”的设计思想,不允许隐式类型转换,因此相互兼容的不同类型间的赋值需要开发人员进行类型转换操作。类型转换语法格式如下:
<结果类型变量>:=<目标类型>(<表达式>)
参考如下示例:
package main
import "fmt"
func main(){
var var1 float32 = 4.4
fmt.Printf("%T->%v\n", var1, var1)
var2 := float64(var1)
var3 := int32(var1)
fmt.Printf("%T->%v\n", var2, var2)
fmt.Printf("%T->%v\n", var3, var3)
//var4 := []byte(var1) //cannot convert var1 (type float32) to type []byte
}
程序输出:
float32->4.4
float64->4.400000095367432
int32->4
需要注意两点:
(1)当类型不兼容的时候是无法转换的,比如上例中的var4 := []byte(var1)
会报编译错误;
(2)非数值间相互转换不会丢失精度,数值间相互转换就需要考虑精度可能丢失的情况。比如上例中将float32转为int32,将丢失小数点后的小数部分。
2.类型断言
在处理由外部传入的数据时,想要创建一个通用的函数,我们需要使用 interface{} 类型接收实参,即空接口类型。
由于空接口类型中不包含任何方法,所以 Go 中的所有类型都实现了 interface{}。我们可以使用类型断言将一个 interface{} 类型的值转换为实际类型的值,即类型断言接受一个接口值, 并从中提取具体类型的值。
使用类型断言有以下两种方式:
// 安全类型断言,失败时 value 为类型 T 的零值
value, ok := expression.(T)
// 非安全类型断言,失败时会 panic
value := expression.(T)
expression 允许为 nil,即不表示任何具体类型时,此时断言 ok 将为 false。
使用示例:
func main() {
var a interface{} = 1
var b interface{} = "abc"
c,ok := a.(int)
d := b.(string)
fmt.Println(c, ok)
fmt.Println(d)
}
输出结果:
1 true
abc
3.类型选择
通过 interface{} 接收的变量类型可能有多种,此时我们需要进行类型选择,即使用 switch 配合类型选择,分发到具体情况(case)进行处理。
如果值为 nil 也是可以进行类型选择的。
参考如下示例:
package main
import "fmt"
func main(){
var b bool=true
var f64 float64=4.4
var str string="dablelv"
var i int=4
var slice []byte
classifier(b, f64, str, i, slice, nil)
}
func classifier(items ...interface{}){
for i,v := range items {
switch v.(type) {
case bool:
fmt.Printf("index=#%d value=%v is bool\n",i,v)
case float64:
fmt.Printf("index=#%d value=%v is float64\n",i,v)
case string:
fmt.Printf("index=#%d value=%v is string\n",i,v)
case int:
fmt.Printf("index=#%d value=%v is int\n",i,v)
default:
fmt.Printf("index=#%d value=%v is %T\n",i,v,v)
}
}
}
输出结果:
index=#0 value=true is bool
index=#1 value=4.4 is float64
index=#2 value=dablelv is string
index=#3 value=4 is int
index=#4 value=[] is []uint8
index=#5 value=<nil> is <nil>