基础数据类型
整数类型
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-i
newSlice:=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]string
colors["red"]="#da1337"
正确做法:
colors:=map[string]string
colors["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 string
email string
age 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,后面依次+1
blue
black
)
指针操作
Go语言提供了指针。指针是一种直接存储了变量的内存地址的数据类型。在其它语言 中,比如C语言,指针操作是完全不受约束的。在另外一些语言中,指针一般被处理为“引 用”,除了到处传递这些指针之外,并不能对这些指针做太多事情。Go语言在这两种范围中取 了一种平衡。指针是可见的内存地址,&操作符可以返回一个变量的内存地址,并且操作符 可以获取指针指向的变量内容,但是在Go语言里没有指针运算,也就是不能像c语言里可以对 指针进行加或减操作
**编译器会给我们隐式地插入 和&操作符,来完成解引用和取地址操作。**
不管你的method的receiver是指针类型还是非指针类型,都是可以通过指针/非指针类型
进行调用的,编译器会帮你做类型转换。
在声明一个method的receiver该是指针还是非指针类型时,你需要考虑两方面的内部,第
一方面是这个对象本身是不是特别大,如果声明为非指针变量时,调用会产生一次拷
贝;第二方面是如果你用指针类型作为receiver,那么你一定要注意,这种指针类型指向
的始终是一块内存地址,就算你对其进行了拷贝。熟悉C或者C艹的人这里应该很快能明
白。