基础数据类型
整数类型
go中int类型最大最小值没有宏定义,需要自己写
// 对64位系统来说int默认为64位
uintMax := ^uint(0)
uintMin := uint(0)
二进制数首位为0表示正数,1为负数
故对于一个byte来说,表示-128(1000 0000) ~ +127(0111 1111)
intMAX := int(^uint(0) >> 1)
intMin := ^intMAX
复合数据类型
切片: 动态数组
//>>>>>>>>>>>>>>>>>>切片初始化slice :=[...]int{1,2,3,4,5} // 容量与初始化值一致slice := make([]int, 5,5])slice := []int{1, 2, 3, 4, 5, 6, 7}newSlice:=slice[1:4] // 与slice共享内存//>>>>>>>>>>>>>>>>>>切片追加//当使用append 追加元素时,默认会看原数组的容量[i,j,k] len=j-i,cap=k-inewSlice:=slice[1:4:4] 限制长度和容量一致,这样只要一次append就能与原数组脱离newSlice:=append(newSlice,1) 现在独立于slice//>>>>>>>>>>>>>>>>>>切片合并newSlice=append(newSlice, slice...) // 注意...操作//>>>>>>>>>>>>>>>>>>range迭代,range 创建的时贝格元素的副本而不是引用for i,v:=range slice{fmt.Println(i,v)}//>>>>>>>>>>>>>>>>>传统迭代for idx:=0;idx<len(slice);idx++{fmt.Println(idx,slice[idx])}//>>>>>>>>>>>>>>>>>>多维切片slice:=[][]int{{10},{100,200}}slice[0]:=append(slice[0],20)//>>>>>>>>>>>>>>>>>> 函数间传递//将切片复制到任意函数都不会对底层数组有影响,复制只会涉及切片本身
映射:存储无序键值对的哈希表
>>>>>>>>>>声明dict:=make(map[string]int) // make映射dict:=map[string]string{"red":"#da1337","orange":"#ee95a22"} //初始化键值对dict:=map[int][]string{} // 一个键对应一个切片// 通过声明映射创建一个nil映射, 直接赋值将报错var colors map[string]stringcolors["red"]="#da1337"正确做法:colors:=map[string]stringcolors["red"]="#da1337">>>>>>>>>>>>>>>>>查询value,ok:=colors["blue"]if ok{fmt.Println(value)}for key,value:=range colors{fmt.Println(key,value)}>>>>>>>>>>>>>>>> 删除键delete(colors,"coral")>>>>>>>>>>>>> 函数间传递映射在函数间的传递不会制造映射的副本,所有的引用都能察觉到更改
自定义类型
// 自定义类型type myint int// 定义一个user类型type user struct{name stringemail stringage int}//类型的声明,默认初始化值均为零值,数值型为0,布尔型为false,字符串型为空var bill user// 使用结构字面量来声明变量lisa:=user{name: "lisa"email: "2513@qq.com"age: 12}// 可以给用户自定义的类型添加行为方法,即在关键字func 和方法名之间添加一个参数// notify 使用值接收实现了一个方法func (u user)notify(){fmt.Println(u.name,u.email)}// 值接收者使用值的副本来调用方法,而指针接收者顺颂实际值来调用方法func (u *user)changeEmail(email string){u.email=email}func main(){bill:=user{"bill","qq.com"} // 值创建lisa:=&user{"lisa","sina.com"} // 指针创建bill.changeEmail("sina.com")lisa.changeEmail("qq.com")}
引用类型
go中引用类型有:切片,映射,通道,接口,函数类型
要使得包中的未公开变量(即小写字母开头)被外部使用,可以用一个工厂函数
枚举类型
const (red = iota # iota 出现的地方置为0,后面依次+1blueblack)
指针操作
Go语言提供了指针。指针是一种直接存储了变量的内存地址的数据类型。在其它语言 中,比如C语言,指针操作是完全不受约束的。在另外一些语言中,指针一般被处理为“引 用”,除了到处传递这些指针之外,并不能对这些指针做太多事情。Go语言在这两种范围中取 了一种平衡。指针是可见的内存地址,&操作符可以返回一个变量的内存地址,并且操作符 可以获取指针指向的变量内容,但是在Go语言里没有指针运算,也就是不能像c语言里可以对 指针进行加或减操作
**编译器会给我们隐式地插入 和&操作符,来完成解引用和取地址操作。**
不管你的method的receiver是指针类型还是非指针类型,都是可以通过指针/非指针类型
进行调用的,编译器会帮你做类型转换。
在声明一个method的receiver该是指针还是非指针类型时,你需要考虑两方面的内部,第
一方面是这个对象本身是不是特别大,如果声明为非指针变量时,调用会产生一次拷
贝;第二方面是如果你用指针类型作为receiver,那么你一定要注意,这种指针类型指向
的始终是一块内存地址,就算你对其进行了拷贝。熟悉C或者C艹的人这里应该很快能明
白。
