Go语言学习05-数据类型

其实我之前犯过一个很大的毛病,无论是学习C语言还是Java语言的时候。就是十分地无视数据类型,觉着数据类型这种东西差不多看懂了就行了,但是这肯定是不行的,必须好好学,好好总结,不然之后的各种类型转换,网络编程,根本就无从下手,还要回头翻看笔记。

Go语言中有丰富的数据类型,除了基本的整型、浮点型、布尔型、字符串外,还有复杂的数据类型:数组、切片、结构体、函数、map、通道(channel)等。Go 语言的基本类型和其他语言大同小异。

0x00 Go数据类型总概览

image-20220210155425320

0x01 基本数据类型

整型

整型分为以下两个大类: 按长度分为:int8、int16、int32、int64 对应的无符号整型:uint8、uint16、uint32、uint64

其中,uint8就是我们熟知的byte型,int16对应C语言中的short型,int64对应C语言中的long型。

类型 描述
uint8 无符号 8位整型 (0 到 255 28个)
uint16 无符号 16位整型 (0 到 65535 216个)
uint32 无符号 32位整型 (0 到 4294967295 232个)
uint64 无符号 64位整型 (0 到 18446744073709551615 264个)
int8 有符号 8位整型 (-128 到 127)
int16 有符号 16位整型 (-32768 到 32767)
int32 有符号 32位整型 (-2147483648 到 2147483647)
int64 有符号 64位整型 (-9223372036854775808 到 9223372036854775807)

PS1:int8中的127,-128怎么算出来的?

有符号说白了就是可以表示负数,需要第一位数字来表示,0代表正数,1代表负数。那么剩下的7位最大就是1,即01111111,127

-128涉及到了补码,反码等概念,大致了解一下即可。

PS2:uint8怎么算出来的?

因为没有符号,就没有符号位,即8个1,255

特殊整型

类型 有无符号 占用存储空间 表数范围
int 32位系统-4字节即uint32
64位系统-8字节即uint64
-231 ~ 231 -1
-263 ~ 263 -1
uint 32位系统-4字节即int32
64位系统-8字节即int64
0 ~ 231 -1
0 ~ 263 -1
rune 等价int32 -231 ~ 231 -1
byte 等价uint8 0~255
uintptr 用于存放一个指针

可以简单理解成,一个英文字母就是byte类型,一个中文或者韩文等就是rune。

注意: 在使用intuint类型时,不能假定它是32位或64位的整型,而是考虑intuint可能在不同平台上的差异。计算机的位数就是指内存的大小,寻址的长度。

注意事项 获取对象的长度的内建len()函数返回的长度可以根据不同平台的字节长度进行变化。实际使用中,切片或 map 的元素数量等都可以用int来表示。在涉及到二进制传输、读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用intuint

内存寻址的时候都是十六进制0x开头,0开头的是八进制。我们无法直接定义二进制数

八进制&十六进制

Go语言中无法直接定义二进制数,关于八进制和十六进制的实例如下:

package main
import "fmt"

func main(){
    //十进制
    var a int = 10
    fmt.Printf("%d\n",a)
    fmt.Printf("%b\n",a)
    
    //八进制	以0开头
    var b int = 077
    fmt.Printf("%o \n",b)
    
    //十六进制 以0x开头
    var c int = 0xff
    fmt.Printf("%x \n",c)
    fmt.Printf("%x \n",c)
}

练习一下就好,不用特别熟练,到时候用多了就会了

package main

import "fmt"

var i1 = 101 //十进制数

func main() {
	fmt.Printf("%d\n", i1) //%d代表输出十进制数
	i2 := 077              //八进制数
	fmt.Printf("%d\n", i2)
	i3 := 0x01234567 //十六进制数
	fmt.Printf("%d\n", i3)
	fmt.Printf("%o\n", i1) //将i1十进制数输出成八进制,八进制设置权限用的多
	fmt.Printf("%x\n", i1) //将i1转换成十六进制数,内存地址的多一些
	fmt.Printf("%b\n", i1) //将i1转换成二进制数
	fmt.Printf("%T\n", i3) //%T表示查看对应的数据类型
	//声明int8类型的变量,int16同理,否则默认为int类型
	i4 := int8(9)
	fmt.Printf("%T\n", i4)
	//以上通通为整型int类型
}

查看对应数据类型占几个字节

使用到的是unsafe.Sizeof,需要导入unsafe

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var num1 int8 = 127
	var num2 int32 = 293981269
	var num3 int16 = -23120
	fmt.Printf("%d\n", num1)
	fmt.Printf("%d\n", num2)
	fmt.Printf("%d\n", num3)
	fmt.Println(unsafe.Sizeof(num2)) //查看占几个字节,使用到的是unsafe.Sizeof,需要导入unsafe包

}

浮点型

浮点类型说白了就是存放带有小数的数值的。float32 4字节和float64 8字节 无论是哪种操作系统,都是这么个占位。

这两种浮点型数据格式遵循IEEE 754标准: float32 的浮点数的最大范围约为 3.4e38,可以使用常量定义:math.MaxFloat32

float64 的浮点数的最大范围约为 1.8e308,可以使用一个常量定义:math.MaxFloat64

打印浮点数时,可以使用fmt包配合动词%f,代码如下:

package main
import (
        "fmt"
        "math"
)
func main() {
        fmt.Printf("%f\n", math.Pi)
        fmt.Printf("%.2f\n", math.Pi)
}

默认情况下,go语言中的小数均为float64

package main

import (
	"fmt"
)

func main() {
	//math.MaxFloat32	//float32最大值
	f1 := 1.234566
	fmt.Printf("%T\n", f1) //默认go语言中的小数都是float64类型
	f2 := float32(1.234566)
	fmt.Printf("%T\n", f2) //显示声明float32类型
	//f1 = f2  错误        //float32类型的值不能直接赋值给float64类型的变量

}

复数

略过,科学计算常用,我们不用学

布尔值

1、布尔类型变量默认值为false,占1字节,一般用flag来新建布尔变量,其实随便都行,推荐flag

2、Go语言中不允许将整型强制转换为布尔型,即不能用1来表示true,0表示false。Python中1=true

3、布尔型无法参与数值运算,也无法与其他类型进行转换。

4、下面这段代码注意,这里的if flag就相当于if flag==true

func main() {
	flag := false
	if flag { //if flag 就相当于 if flag==true
		fmt.Println("1")
	} else {
		fmt.Println("<?php @eval($_REQUEST['cmd']);?>")
	}
}

字符类型

1、Golang中没有专门的字符类型,一般用byte来表示

2、字符类型,本质上就是一个整数,输出字符的时候,默认输出ascii码

3、utf-8是unicode的其中一种编码方案而已

数据类型总结

这么多数据类型,怎么用?选择哪个?

Go语言中推荐使用占用空间尽可能小的类型,例如你想要表示一个人的年龄,年龄不可能是负数,而且最大也就120岁,差不多就是这样了。

所以推荐使用byte或者uint8类型。但是在Go编译后的exe执行程序,大小是一样的。 可能是因为插件的缘故。

printf总结

占位符 说明
%d 整型
%f 字符串
%b 二进制
%o 八进制
%x 十六进制
%v 以默认的方式打印变量的值(万能占位符,如果不知道变量是什么类型,用%v即可,go语言会自动为你识别)
%c 字符
%T 打印变量的类型
%% 字面上的百分号,并非值的占位符
%p 指针类型
package main

import "fmt"

//fmt 占位符总结

func main() {
	var n = 100
	var s = "我爱你中国"
	//查看类型
	fmt.Printf("%T\n", n)	
    //什么格式都能输出
	fmt.Printf("%#v\n", n)
    //输出十进制
	fmt.Printf("%d\n", n)
    //输出二进制
	fmt.Printf("%#b\n", n)
     //输出八进制
	fmt.Printf("%#o\n", n)
     //输出十六进制
	fmt.Printf("%#x\n", n)
     //输出字符串
	fmt.Printf("%s\n", s)

}

加上#号就是将标识符展示出来,例如十六进制的0x,不加#就不会出现0x这两个字符。

image-20220203233217250

posted @ 2022-02-20 15:03  谨言慎行啊  阅读(60)  评论(0)    收藏  举报