go的数据类型分为四大类:基础类型、聚合类型、引用类型、接口类型
基础类型
1. 整形(int):就是表示整数值,不同类型不能直接比较,但是都可以和字面量比较,所谓的字面量就是直接的数值,如10 10.2
var v1 int32 =10
var v2 int =10
//编译错误:invalid operation: v1 == v2 (mismatched types int32 and int)
if v1==v2{
}
//编译通过
if v1==10{
}
整形数据类型共有int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64,uintptr
11种
类型 | 描述 |
---|---|
int8 | 长度为8位的整数,表示[2^-7, 2^7-1] |
byte | 长度为8位的整数,和int8同等 |
int16 | 长度为16位的整数 |
int32 | 长度为32位的整数 |
rune | 长度为32位的整数,和int32同等 |
int | 默认长度为32位,但是和int32之间仍需要显示转换 |
int64 | 长度为64位的整数 |
uint8 | 长度为8位的非负整数 [0, 127] |
uint16 | 长度为16位的非负整数 |
uint32 | 长度为32位的非负整数 |
uint64 | 长度为64位的非负整数 |
uintptr | 大小不明确,但是足以完整存放指针,仅仅用于底层编程 |
取模运算符的余数的符号均与被除数相同:
-5 % 3 = -2; -5 % -3 = -2
2. 浮点数(float):
类型 | 描述 |
---|---|
float32 | IEEE-754 32位浮点型数 |
float64 | IEEE-754 64位浮点型数 |
3. 复数(complex):
类型 | 描述 |
---|---|
complex64 | 32 位实数和虚数 |
complex128 | 64 位实数和虚数 |
var x complex128 = complex(1,2) //1+2i
real(x) //复数的实数部分:1
imag(x) //复数的虚数部分:2
4. 布尔值(bool):bool类型不支持类型转换,不能将其他类型转为bool类型。bool类型只有两个值true
和false
,支持所有的逻辑运算,如:&& || !等等
5. 字符串(string):不可变的字节序列。Go语言中的字符串和java中的String类一样,是不可变的
- len()函数获取字符串长度
- str[i]下标获取字符串中第i个字符
- [i:j]获取字符串的子串,包括i,不包括j
- 可以使用
==
和<
等符号比较字符串,比较根据字典排序 - 因为字符串不可变,所有不能给内部字符赋值:如s[0]=’c’是不允许的
- 字符串字面量:“括起来的字符串,其中的转义序列不起作用,回车符会被删除,只保留换行符。
- string(65):”A”而不是65
- 中文在utf-8中表示3个字符
6. 常量:可以使用itoa生成器,默认从0开始
const(
sunday int itoa
monday
tuesday
wednesday
thursday
friday
saturday
)
- 无类型常量:直接赋值,不定义类型;无类型布尔,无类型整数,无类型文字符号,无类型浮点数,无类型复数,无类型字符串,
const(
a = 1
b
c = 2
d
// a=b=1 c=d=2
)
- 变量声明中如果没有显示的定义类型,无类型常量会隐式地转换为改变量的默认类型,默认
int,float64,string
i = 10
f = 10.2
s = "hello Go"
复合数据类型
1. 数组:数组是不可变长序列
- 数组长度在定义的时候必须是常量,也就是在编译期间就要能够确定数组的长度。
- 数组的长度是作为数组数据结构的一部分,两个不同长度数组变量不能相互赋值;
- 数组的长度取决于数组的索引最大值;
var arr [3]int
var arr [3]int = [3]int{1,2,3}
q := [...]int{1,2,3}//数组长度有初始化的个数决定
len(arr)//获取数组的长度
- 数组可以直接设定索引和值,此时索引可以是不按照顺序来的
arr := [...]int{1:1,2:2,5:5,4:4}
- 数组是可以比较的,前提是数组的长度和类型要一致,如果不一致会出现编译错误,一致的情况下比较对应索引下的值是否都相等。
arr := [3]int{1,2,3}
arr2 := [3]int{4,5,6}
//arr<arr2,数组类型相同,长度相同,可以比较
arr<arr2
arr3 := [5]int{1,2,3,4,5}
//invalid operation: arr == arr3 (mismatched types [3]int and [5]int)
arr==arr3
2. slice:可变长序列,可以用来访问数组的部分或者全部的元素,包含三个属性:指针,长度和容量;
- cap:指的是slice起始元素到数组最后一个元素的长度
arr := [5]int{1,2,3,4,5}
//1,2,3
sli := arr[0:3]
//表示从第一元素1到数组最后一个元素5的长度,为5
cap(sli)
//2,3
sli2 := arr[1:3]
//表示从sli2的第一个元素2到数组最后元素5的长度,为4
cap(sli2)
- slice可以在自身的基础上扩容,
s1 := s[3:6] s2:=s1[:5]
s1只有数组s中第3,4,5三个元素,s2变成了第3,4,5,6,7五个元素了。前提s中至少有这些元素。 - slice的引用不能超过被引用对象的容量,即cap,否则会出现恐慌
panic: runtime error: slice bounds out of range
- slice的引用可以超过被引用对象的长度
- slice的零值是nil,如果要检查一个slice是否为空,直接使用len()函数,因为slice为空,slice可能不为nil
- slice可以用来实现栈,入栈:
stack = append(stack,v)
出栈:value = stack[len(stack)-1] stack=stack[:len(stack)-1]
make([]T,lens,caps)
s []int //不包含长度定义
s[i:j] //从数组或者slice中获取从i-j的数值,包括i,不包括j;
s[:j] //从0-j
s[i:} //从i到len(s)
var s []int //len为0,s==nil
s = nil //len为0,s==nil
s = []int(nil) //len为0,s==nil
s = []int{} //len为0,s!=nil
len(s) //返回slice的长度
cap(s) //返回slice的容量
append(s,v1,v2) //返回s加上v1,v2后的slice
append(s,s2...) //可以在slice中添加其他的slice但是需要加上...,将s2打散为若干个元素
copy(s,s1) //将s1中的元素赋值到s中,替换的元素个数为两者中最短的长度,返回复制的长度
3. map:键值对,使用散列表实现
- 使用delete(map,value)删除的时候,即使方法中的键不存在,此方法也是安全的
- map元素不是一个变量,不能获取其中的地址
- map中迭代的顺序是不固定的,因为使用的散列算法不同
- map使用之前必须初始化
- 当key不在map中的时候,获取的值为所对应类型的零值
ages := make(map[string] int)//创建一个map
ages["alice"] = 31
ages["bob"] = 34
ages := map[string]int{
"alice" : 31,
"bob" : 34,
}
//删除map中的元素
delete(ages,"alice")
//判断键是否存在map中,如果不存在执行相应操作
if age,ok :=age["bob"]; !ok{...}
4. 结构体:将零个或者多个任意类型的命名变量组合在一起的聚合数据类型
- 通过点号来访问数据,
student.ID
;也可以通过获取成员变量的地址来获取 - 结构体中不能包含自身类型的变量,但是可以包含自身类型指针的变量
- 成员变量的顺序对于结构体很重要,如果顺序改变,也就是定义了一个新的结构体
- 结构体字面量
- 结构体可以比较,可以作为map的键存在
- 匿名成员
- 结构体指针可以直接访问结构体中的成员,而不需要使用
*
- 可以使用字段设置值,
str := struct{x:1,y:2}
type Employee struct{
ID int
Name string
Address string
DoB time.Time
Position string
Salary int
ManagerID int
}
var Bob Employee
position := &Bob.position
*position = “Senior ”+ *position
//结构体字面量,形如java的构造器
type Point struct{x,y int}
p := Point{1,2}
//通过指针初始化结构体
pp := &Point{1,2}
//匿名成员
type Point struct{
X int
Y int
}
type Circle struct{
Point
Radius int
}
type Wheel struct{
Circle
Spokes int
}
//
var w Wheel
w.X = 8//等价与w.Circle.Point.X = 8
w.Y = 8
5. 指针: *T表示T类型的指针,其零值为nil
var i = 2
var intptr *int = &i
i = *intptr
6类型判断: i.(T)判断值i中是否是类型T,如果是,则将T类型的值赋值给i,如果不是,则会触发一个painc,这时候需要使用val,ok:=i.(T)
,如果是T类型,ok返回true,如果不是返回false。还能用于switch-case结构中。前提变量i要是一个接口类型的变量,否则会报错invalid type assertion: i.(int) (non-interface type int on left)
switch i.(type){
case int32:
case float64:
}
Go语言编程