Go语言面试系列:Go基础类型大全
go语言自带的基础类型包括
- int :有符号的整数类型,具体占几个字节要看操作系统的分配,不过至少分配给32位。
- uint:非负整数类型,具体占几个字节要看操作系统的分配,不过至少分配给32位。
- int8:有符号的整数类型,占8位bit,1个字节。范围从负的2的8次方到正的2的8次方减1。
- int16:有符号的整数类型,占16位bit,2个字节。范围从负的2的16次方到正的2的16次方减1。
- int32:有符号的整数类型,占32位bit,4个字节。范围从负的2的32次方到正的2的32次方减1。
- int64:有符号的整数类型,占64位bit,8个字节。范围从负的2的64次方到正的2的64次方减1。
- uint8:无符号的正整数类型,占8位,从0到2的9次方减1.也就是0到255.
- uint16:无符号的正整数类型,占16位,从0到2的8次方减1.
- uint32:无符号的正整数类型,占32位,从0到2的32次方减1.
- uint64:无符号的正整数类型,占64位,从0到2的64次方减1.
- uintptr:无符号的储存指针位置的类型。也就是所谓的地址类型。
- rune :等于int32,这里是经常指文字符。
- byte:等于uint8,这里专门指字节符
- string:字符串,通常是一个切片类型,数组内部使用rune
- float32:浮点型,包括正负小数,IEEE-754 32位的集合
- float64:浮点型,包括正负小数,IEEE-754 64位的集合
- complex64,复数,实部和虚部是float32
- complex128,复数,实部和虚部都是float64
- error,错误类型,真实的类型是一个接口。
- bool,布尔类型
int8 和uint8 后面的8指的是占得位数,因为有符号的第一位作为符号位置,所以它真的可以计数的位置只有7个了,第一位表示正负,无符号的整数显然没有这个烦恼。
go语言的基础组件分为以下几种:
其中按照是否是引用类型(指针类型)分为引用类型和非引用类型,他们分别是
引用类型 | 非引用类型 |
---|---|
slice,interface,chan,map | array,func,struct,大部分的内置类型 |
这里要说明以下,所有的非引用类型的初始化值都是一个具体的值,只有引用类型的初始化是nil
,nil在go里面就是指的是空。是不能直接使用的。
全局变量,引用类型的分配在堆上,值类型的分配在栈上。
局部变量,一般分配在栈上。如果局部变量太大,则分配在堆上。如果函数执行完,仍然有外部引用此局部变量,则分配在堆上。
我们分别来介绍以下他们。
array
数组,我们先看一下数组的初始化。
// 给数组进行初始化
// 初始化的方式1
a := [6]string{
}
// 初始化的方式2
var a [6]string
这里稍微提一下,在go里面的赋值符号有两种:
var a
b :=
其中var 这种方式不论是局部还是全局变量都可以使用,但是后者也就是:=
只有局部变量可以使用。也就是只有函数内部才能使用。
并且,var后面的变量后面的类型是可以省略的,省略后,go会在编译过程中自动判断。所以如果不省略就是长这样.
var a int
说到了变量,go里面当然也有定量,使用const来命名,一般都是全局使用。
// 根据习惯一般用大写表示定量
const PAI = 12
同样的,定量也可以省略后面的类型。
接下来我们看一下数组的赋值
a[0] = "0"
a[1] = "1"
a[2] = "2"
a[3] = "3"
a[4] = "4"
a[5] = "5"
这里要点明一下,值类型,或则说非引用型类型的“声明” 就等于初始化,也就是说,当你给一个变量声明一个值类型的数据时,就自动给定了初始值。
这里谈一下他们的初始值:
array | int | string | bool | float | func | struct |
---|---|---|---|---|---|---|
空数组,但不是nil,已经占用了声明的数组长度 | 0 | 空字符串,通常我们使用""代指空字符串 | false | 0 | 就是一个空的函数 | 一个空的structure |
length <4 的数组,数据是直接存在栈空间上的,如果数据大于4,那么会存放在静态空间,然后才复制到栈空间上,顺便说一下,堆和栈属于动态存储,其中栈是操作系统直接控制,我们的局部变量,不逃逸的情况下都是存在于栈中,逃逸了就去堆里面了,说完了动态,静态存储区域包含了两者,一个是存储的常量,一个是存储的静态变量,常量好理解就是const来声明的常量,静态变量,比如这里大于4的数组。
数组的语法糖[...]int
使用这种方式,必须在声明的时候直接赋值,否则下面进行赋值的时候,系统不知道你的length到底是多少,就会"out of index"
数组的初始化的中括号里要么是...
, 要么就是个常量,不能是变量
关于go里面的比较问题
只有类型一致的情况下,进行比较,比如struct int,等,接口也可以比较,slice map 以及函数体,都是无法进行比较的。chan 可以比较,但是即使是类型一样,也是false的结果,nil也是可以比较的,因为nil的底层是 var nil Type
type Type int
也就是说nil其实是一个值类型。nil也是有类型的,比如说接口的nil就是接口类型,那么指针类型的nil就是指针类型,slice的nil就是这个slice类型。
一直在变的无法比较,一成不变的就可以比较,slice和map都因为底层指向可以一直变所以无法比较,函数体内部也是一直可以变,所以只有他们三个无法进行比较。
slice
切片,是一个内置的引用类型,其实质是一个structure,也就是说是一个结构体,这个结构体内部含有一个指向某个数组的地址,所以说我们可以简单的来理解,slice是某个数组的指针。
type SliceHeader struct {
// 指向底层数组的指针类型
data uintptr
// 长度
len int
// 容量
cap int
}
切片的初始化:
a := make([]string,10)
// 或者
var b [10]string
a :=