Go数据类型

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类型只有两个值truefalse,支持所有的逻辑运算,如:&& || !等等

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
arr[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语言编程

你可能感兴趣的:(Go)