GO语言数值类型
和任何语言一样,数值类型肯定是Go类型中必不可少的一种数据类型,但同时,Go中的数值类型又有许多不同于其他语言的地方。接下来来看看吧。
分类
从大类上看,Go的数值类型分为整形和浮点型两种,而Go中的浮点型不像java分成了单精度(float)和双精度(double)两种。总的来说,Go的数值类型按照占字节的大小分为了好几种。
整形int
因为种类繁多,我将整形称为int系列,哈哈。首先int类型分为有符号与无符号两种。有符号位指的是该数的最高位可以用负数来表示,这里就不详细说了,有兴趣的可以看看这篇文章:
https://www.cnblogs.com/lazycoding/archive/2011/03/21/unsigned-signed.html
其中:
-
有符号位分为int 8、int 16、int 32、int 64四种,它们分别占1、2、4、8个字节
-
无符号位分为unit8、unit16、unit32、unit64四种,所占字节与有符号位一致
还有一个比较特殊的关键字int,在你使用它声明变量时,发现它的长度和取值范围是与int64一致的,但这并不代表int就等于int32,实际上int的关键字是根据机器决定的,当你的机器是32位时,int能代表的长度则为int32的长度,而当你的机器是64位时,int则代表int64度长度。
接下来放上一张表来将int的所有类型列出来吧:
类型 | 有无符号 | 存储空间 | 值范围 | 备注 |
---|---|---|---|---|
uint8 | 无 | 8-bit | 0 ~ 255 | |
uint16 | 无 | 16-bit | 0 ~65535 | |
uint32 | 无 | 32-bit | 0 ~ 4294967295 | |
uint64 | 无 | 64-bit | 0~18446744073709551615 | |
int8 | 有 | 8-bit | -128 ~ 127 | |
int16 | 有 | 16-bit | -215 ~ 215-1 | |
int32 | 有 | 32-bit | -231 ~ 231-1 | |
int64 | 有 | 64-bit | -263 ~ 263-1 |
接下来我们结合之前的变量声明的几种方式,对几种整形变量进行声明:
var int1 int=100
int2:=1100
var int3 int32=32
var int4=23343
接下来格式化输出它们:
fmt.Printf("int1=%T,int2=%T,int3=%T,int4=%T\n",int1,int2,int3,int4)
这里既然提到了格式化输出方式printf,以及我们经常用的普通输出方式print,接下来就列一列几种输出方式,以及格式化输出的几种格式吧:
几种输出方式
- Print: 输出到控制台,不接受任何格式化操作
- Println: 输出到控制台并换行
- Printf : 只可以打印出格式化的字符串。只可以直接输出字符串类型的变量(不可以输出别的类型)
- Sprintf:格式化并返回一个字符串而不带任何输出
- Fprintf:来格式化并输出到 io.Writers 而不是 os.Stdout
格式化输出格式
格式 | 说明 |
---|---|
%d | 格式化整数 |
%0d | 用于规定输出定长的整数 其中开头的数字 0 是必须的 |
%g | 格式化浮点型 |
%n.mg | 用于表示数字 n 并精确到小数点后 m 位,除了使用 g 之外,还可以使用 e 或者 f |
%f | 格式化浮点数 |
%X , %x | 格式化 16 进制表示的数字 |
%b | 位的格式化标识符 |
%e | 科学计数表示法 |
%t | 格式化布尔型 |
%c | 格式化字符 |
%s | 格式化字符串 |
%U , %u | Unicode,格式为 U+hhhh 的字符串 |
%p | 格式化指针 |
%v | 使用类型的默认输出格式的标识符 |
%T | 打印某个类型的完整说明 |
%#v | 打印包括字段和限定类型名称在内的实例的完整信息 |
%+v | 打印包括字段在内的实例的完整信息 |
接下来我们使用unsafe包中的Sizeof方法来输出以上几种变量的长度:
fmt.Println(unsafe.Sizeof(int1),unsafe.Sizeof(int2),unsafe.Sizeof(int3),unsafe.Sizeof(int4))
运行:
8 8 4 8
可以看到int类型的int1长度与int64类型长度一致,因为我的机器是64位的,而int2和int4我们并没有指定类型,鼠标移上去可以看到系统帮我们推断为了int类型,所以长度也为8
浮点类型
不同于java中的浮点(单精度:float,双精度:double),Go用float32和float64两种类型来分别表示单精度与双精度数字,值得注意的是Go中并不存在float这种数据类型。
其中单精度浮点数float32占4个字节,双精度浮点数float64占8个字节,而在GO中如果我们不指定类型,默认使用的就是float64类型:
十进制表示法
当整数部分为0时,我们可以省略数字前面的0:
var float1=3.1415926
float2:=.1412442
fmt.Printf("float1=%T,占用的字节大小=%d\n",float1,unsafe.Sizeof(float1))
fmt.Printf("float2=%T,占用的字节大小=%d\n",float2,unsafe.Sizeof(float2))
运行:
float1=float64,占用的字节大小=8
float2=float64,占用的字节大小=8
科学计数法
float3:=3.1415926e2 //3.1415926乘以10的2次方
float4:=3.1415926e-2 //3.1415926除以10的2次方
fmt.Println(float3,float4)
运行:
314.15926 0.031415926
精度丢失问题
当我们将小单位向大单位类型的数值类型转换时,会出现精度丢失问题,这一点在许多编程语言中都存在。
复数
复数指的是实数+虚数的组合,在Go中通过complex64和complex128来表示,从名字来看就知道表示的是两种长度不同的复数,其中实数部分就用数字表示,而复数部分用i表示:
var complex1 complex64
complex1=3.14+12i
complex2:=complex(3.14,12)
fmt.Printf("complex1的类型=%T,值=%v\n",complex1,complex1)
fmt.Printf("complex2的类型=%T,值=%v\n",complex2,complex2)
其中,complex64的长度为32位实数+32位虚数,而complex128的长度为64位实数+64位虚数,我们可以通过real()以及imag()方法分别查看一个虚数的实数和复数部分:
fmt.Println(real(complex1),imag(complex1))
运行:
complex1的类型=complex64,值=(3.14+12i)
complex2的类型=complex128,值=(3.14+12i)
3.14 12