在Go语言编程中,数据类型用于声明函数与变量、常量的数据类型。数据类型这个概念主要是为了提高内存的利用效率,因为不同数据存储在内存中所需要的空间大小是不一样的,所以编程时指定数据类型,可以充分利用内存空间,数据存储体积大的类型向系统申请的内存就大一些,数据体积小一点的类型向系统申请的内存就小一点。数据类型确定了程序实体在内存中的存储中可以占用多少空间以及如何存储。
Go语言严格来说一共有9种不同大小的整型,无符号四种,有符号四种,还有一种uintptr类型(多用于底层编程)。其中int8、int16、int32和int64这四种不同大小的有符号整型数类型分别对应8、16、32、64b大小的有符号整型数;对应的无符号整型数分别是uint8、uint16、uint32、uint64;除了指定整数位数以外,也可以直接使用int和uint类型。
Go语言可以根据不同平台的实现对int进行调整,既可以是int32,也可以是int64,uint同理。
在Go语言中所有类型的声明各式都是一样的,就像这样:
var value1 int32 // 全局声明
func main(){
value2 := 64 // 局部声明
}
需要注意的是,不同大小的整型类型是不能直接比较,不能直接运算,如果需要对两个不同类型的值执行运算操作,需要进行类型转换。
Go语言的整型支持常规整数运算,加减乘除自然不必多说,Go语言和C语言一样,使用 **%**表示求余符号,用作求余运算,就像这样:
5 % 3 // 结果:2
除了算术运算,常见的还有比较运算,>、<、==、>=、<= 和 != 等比较符号Go语言都支持(没有三个等号的全等符号):
x,y := 2,4
if x == y{
fmt.Println("x等于y")
}
上面的例子中包含一个if判断流程,当x等于y时输出“x等于y”,否则什么都不输出,尝试修改x和y的值查看输出。前面说过不同类型的整型不能直接进行比较运算,但各种类型的整型变量可以直接与字面常量( 指源程序中表示固定值的符号,例如各种进制下的数字)进行比较,就像这样:
package main
import "fmt"
var x int32
var y int64
func main(){
x,y = 2,4
if x == y{ // 编译通过,因为x与y的类型不一样
fmt.Println("x等于y")
}
if x == 2 || y == 2{
fmt.Println("x等于y")
}
}
编译不通过的if语句是因为尝试比较两个不同类型的整型,自然不能通过编译;编译通过的if语句中,字面常量两个2虽然看起来相等,但其实所表示的是不同类型,在编译运行时,这两个字面常量都会被转换为相应的类型。可以把上面编译通过的代码修改为如下形式:
if x == 999999999999999 || y == 2{ // 编译不通过
fmt.Println("x等于y")
}
编译以上代码会得到constant 99999999999 overflows int32的错误,因为99999999999999已经超过了int32的范围。
Go语言整形数据也支持位运算,详见下表:
运算 | 例子 | 结果 |
---|---|---|
x<1<<2 |
4 |
|
x>>y,右移 | 12>>2 | 3 |
x^y,异或 | 1^2 | 3 |
x&y,与 | 1&2 | 0 |
x|y,或 | 1|2 | 2 |
^x,取反 | ^2 | -3 |
使用方法与主流编程语言java、python并无差异
浮点型用于表示包含小数点的数据,比如3.14就是一个浮点型数据。Go语言提供了两种精度的浮点数:float32和float64,在Go语言中没有float这种类型。float这种类型。float32精确到小数点后7位,float64精确到小数点后15位。由于精度不同的缘故,在使用==或者!=来比较浮点数时需要也别注意的,事先测试运算可以避免不少问题。
由于标准库math包中所有有关数学运算的函数都要求接收float64,省去后续类型转换的工作
Go语言定义一个浮点型变量
package main
import (
"fmt"
"reflect"
)
func main(){
var value1 float46
value1 = 1 // 不管是否是有小数点,value1都是浮点型
value2 := 2 // 如果没有小数点,value2会被Go语言的编译器推导为整型
value3 := 3.0 // 如果有小数点,value3会被推导为浮点型
// v := value1 + value2 // 编译失败,value1和value2类型不同
v := value1 + value3
fmt.Println(value1,value2,value3,v)
fmt.Println("v的类型是:",reflect.TypeOf(v))
}
上面的代码中使用了反射(reflect)的概念返回变量的类型,修改TypeOf的变量名称,查看其他值的类型是否如你所想。
浮点型的加减乘除运算和整型没有差别,不同的是浮点型有一些特殊,因为浮点型的精度不同会导致比较结果与预期不同,就像这样:
package main
import (
"fmt"
)
func main(){
var value1 float64
value1 = 1
value2 := 1.0000000000000000000000000001
if value1 == value2{
fmt.Println("value1与value2相等")
}
}
上面两个变量显然不相等,但是因为精度限制在小数点后15位,之后的数字会被编译器舍弃,所以程序会返回两个实际上不相等的变量相等。