基础数据类型

整数类型
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

复合数据类型

切片: 动态数组

  1. //>>>>>>>>>>>>>>>>>>切片初始化
  2. slice :=[...]int{1,2,3,4,5} // 容量与初始化值一致
  3. slice := make([]int, 5,5])
  4. slice := []int{1, 2, 3, 4, 5, 6, 7}
  5. newSlice:=slice[1:4] // 与slice共享内存
  6. //>>>>>>>>>>>>>>>>>>切片追加
  7. //当使用append 追加元素时,默认会看原数组的容量
  8. [i,j,k] len=j-i,cap=k-i
  9. newSlice:=slice[1:4:4] 限制长度和容量一致,这样只要一次append就能与原数组脱离
  10. newSlice:=append(newSlice,1) 现在独立于slice
  11. //>>>>>>>>>>>>>>>>>>切片合并
  12. newSlice=append(newSlice, slice...) // 注意...操作
  13. //>>>>>>>>>>>>>>>>>>range迭代,range 创建的时贝格元素的副本而不是引用
  14. for i,v:=range slice{
  15. fmt.Println(i,v)
  16. }
  17. //>>>>>>>>>>>>>>>>>传统迭代
  18. for idx:=0;idx<len(slice);idx++{
  19. fmt.Println(idx,slice[idx])
  20. }
  21. //>>>>>>>>>>>>>>>>>>多维切片
  22. slice:=[][]int{{10},{100,200}}
  23. slice[0]:=append(slice[0],20)
  24. //>>>>>>>>>>>>>>>>>> 函数间传递
  25. //将切片复制到任意函数都不会对底层数组有影响,复制只会涉及切片本身

映射:存储无序键值对的哈希表

  1. >>>>>>>>>>声明
  2. dict:=make(map[string]int) // make映射
  3. dict:=map[string]string{"red":"#da1337","orange":"#ee95a22"} //初始化键值对
  4. dict:=map[int][]string{} // 一个键对应一个切片
  5. // 通过声明映射创建一个nil映射, 直接赋值将报错
  6. var colors map[string]string
  7. colors["red"]="#da1337"
  8. 正确做法:
  9. colors:=map[string]string
  10. colors["red"]="#da1337"
  11. >>>>>>>>>>>>>>>>>查询
  12. value,ok:=colors["blue"]
  13. if ok{
  14. fmt.Println(value)
  15. }
  16. for key,value:=range colors{
  17. fmt.Println(key,value)
  18. }
  19. >>>>>>>>>>>>>>>> 删除键
  20. delete(colors,"coral")
  21. >>>>>>>>>>>>> 函数间传递
  22. 映射在函数间的传递不会制造映射的副本,所有的引用都能察觉到更改

自定义类型

  1. // 自定义类型
  2. type myint int
  3. // 定义一个user类型
  4. type user struct{
  5. name string
  6. email string
  7. age int
  8. }
  9. //类型的声明,默认初始化值均为零值,数值型为0,布尔型为false,字符串型为空
  10. var bill user
  11. // 使用结构字面量来声明变量
  12. lisa:=user{
  13. name: "lisa"
  14. email: "2513@qq.com"
  15. age: 12
  16. }
  17. // 可以给用户自定义的类型添加行为方法,即在关键字func 和方法名之间添加一个参数
  18. // notify 使用值接收实现了一个方法
  19. func (u user)notify(){
  20. fmt.Println(u.name,u.email)
  21. }
  22. // 值接收者使用值的副本来调用方法,而指针接收者顺颂实际值来调用方法
  23. func (u *user)changeEmail(email string){
  24. u.email=email
  25. }
  26. func main(){
  27. bill:=user{"bill","qq.com"} // 值创建
  28. lisa:=&user{"lisa","sina.com"} // 指针创建
  29. bill.changeEmail("sina.com")
  30. lisa.changeEmail("qq.com")
  31. }

引用类型

go中引用类型有:切片,映射,通道,接口,函数类型
要使得包中的未公开变量(即小写字母开头)被外部使用,可以用一个工厂函数

枚举类型

  1. const (
  2. red = iota # iota 出现的地方置为0,后面依次+1
  3. blue
  4. black
  5. )

指针操作

Go语言提供了指针。指针是一种直接存储了变量的内存地址的数据类型。在其它语言 中,比如C语言,指针操作是完全不受约束的。在另外一些语言中,指针一般被处理为“引 用”,除了到处传递这些指针之外,并不能对这些指针做太多事情。Go语言在这两种范围中取 了一种平衡。指针是可见的内存地址,&操作符可以返回一个变量的内存地址,并且操作符 可以获取指针指向的变量内容,但是在Go语言里没有指针运算,也就是不能像c语言里可以对 指针进行加或减操作
**编译器会给我们隐式地插入
和&操作符,来完成解引用和取地址操作。**
不管你的method的receiver是指针类型还是非指针类型,都是可以通过指针/非指针类型
进行调用的,编译器会帮你做类型转换。

在声明一个method的receiver该是指针还是非指针类型时,你需要考虑两方面的内部,第
一方面是这个对象本身是不是特别大,如果声明为非指针变量时,调用会产生一次拷
贝;第二方面是如果你用指针类型作为receiver,那么你一定要注意,这种指针类型指向
的始终是一块内存地址,就算你对其进行了拷贝。熟悉C或者C艹的人这里应该很快能明
白。