5.1.1.类型转换
Go语言提供了一种转换不同但类型兼容的类型的方式,这种转换是非常有用且安全的。对于非数值类型之间的转换不会丢失精度,但是对于数值类型之间的转换,可能会丢失精度或发生其他的问题。例如,如果我们声明x :=uint16(65000),然后使用y := int16(x)进行转换。因为x超出了int16的范围,所以意料之中y的值被设置成-536,但这并非我们所期望的。
下面是类型转换语法:
1 | resultOfType := Type(expression) |
对于数值,基本上我们可以将任意整数或浮点数转换为另一个整数或浮点数类型的值(如果目标类型的范围小于源类型的,可能会丢失精度)。这同样也适用于complex128和complex64 类型之间的转换。
一个字符串可以被转换成一个[]byte类型(底层为UTF-8字节)或[]rune类型(Unicode码点形式)的值,而一个[]byte类型或[]rune类型的值可以被转换成一个字符串。一个字符是一个rune类型(即,int32)的值,并且可以被转换成一个只有一个字符的字符串。字符串和字符之间的转换请参见第三章。
让我们从一个简单的自定义类型开始。
1 | type StringSlice []string |
上面的类型有一个自定义的StringSlice.String()函数(这里未给出),并返回一个使用复合语法创建的自定义的StringSlice中的字符串切片的字符串表示。
1 2 3 4 5 6 7 | fancy := StringSlice{"Lithium", "Sodium", "Potassium", "Rubidium"} fmt.Println(fancy) plain := []string(fancy) fmt.Println(plain) StringSlice{"Lithium", "Sodium", "Potassium", "Rubidium"} [Lithium Sodium Potassium Rubidium] |
我们使用StringSlice类型的fancy本身的StringSlice.String()函数将其打印出来。
但是一旦我们将它转换为[]string切片,它就会像其它[]string一样的形式被打印出来。(如何创建拥有自己的方法的自定义类型,请参见第6章)
如果表达式和Type的底层类型相同,或如果表达式是可以用类型Type表示的无类型常量,或如果Type是一个接口类型而表达式实现了该Type的接口,则将一种类型转换为其他类型是可以正常工作的。