第一章 初识Go语言
Google是Go语言的主推者,开源社区
自动垃圾回收
函数多返回值
内存检查工具 Rational Purify、Compuware BoundsChecker、Parallel Inspector等
内置map 和Slice类型(数组)
不支持继承和重载
goroutine是比线程更轻盈更省资源的协程
支持反射,不能通过类型名称字符串来构造实例
通过Cgo支持对C的重用
可执行程序必须有一个名字为main的包,并且有一个main函数(没有参数,也没有返回值)
log包提供了基础的日志功能
支持GDB调试
第二章 顺序编程
变量声明
var v1 [] string
var (
v1 int
v2 string
)
声明并直接初始化的场景,var可以省略
var v3 = 10
v3:= 10
编译器可以自动推导类型
支持多重赋值 i,j = j,i
函数有多个返回值但是只需要其中一个,可以使用多重赋值+匿名变量
,,v3 := getName()
常量通过const关键字声明
const a,b,c = 3,4,"foo"
内置常量 true false iota(自增,const重置为0)
大写字母开头的常量,包外可见,否则为私有
基础类型 bool int8 byte int16 int unit unitptr float32 float64 complex64 complex128 string rune(字符) error
符合类型 pointer array slice map chan struct interface
字符串可以以数组下标的方式读取,但是不能修改。
内置函数len() 获取字符串长度或者数组长度
range关键字遍历数组、容器
for i,v := range array{
}
数组是值类型,作为参数传递时,进行数据复制,函数中无法修改传入的数组内容
slice 基于数组创建或者通过make创建
mySlice := array[:5]
mySlice := make([]int ,5)
len()获得元素个数 cap()获得容量 append()切片扩容 append(slice1,slice2...) 三个点代表把slice2的所有元素打散后传入,满足不定参数的特点。 copy()支持slice的复制
map使用:
var mymap map[string] PersonInfo
mymap = make(map [string] PersonInfo) 、mymap = make(map [string] PersonInfo, 100)
mymap["123"]=PersonInfo{"1","jack"}
删除用delete(mymap,"123")
查找 value,ok:=mymap["123"] ok为true代表找到
条件语句if :不需要将条件用括号包含起来 {}必须存在 不允许存在return
switch语句的条件对象可以省略,在case后面加上条件判断;不需要使用break来退出case,如果继续执行下一个case,使用fallthrough关键字
循环支持for,不支持while和do while, 省略条件则代表无限循环,如for {sum ++}
break可以后面跟一个label,支持中断那一层的循环。
支持goto语句
函数定义 func Add(a, b int)(ret int ,err error){},参数类型相同可以省略类型描述,如果只有一个返回值,可以写成func Add(a,b int) int {}
对于函数、类型、变量的命名,要注意大小写,大写对其他包开放,小写只对本包开放。
支持不定参数 func myfunc(args ...int) 不定参数必须是最后一个参数;不定参数本质上是一个数组切片 ;不定参数可以使用interface指定为任意类型,arg.(type)获取参数运行时的实际类型。
支持匿名函数,支持闭包,闭包中可以引用外部变量
错误处理,是GO语言的一大亮点
error接口
自定义error接口,实现Error方法。
defer关键字(延迟执行)来完成资源的释放,如果有多条语句,可以使用匿名函数 defer func(){}()
defer关键字遵循先进后出的原则,所有一个defer语句最先被执行。
panic和recover方法的使用
使用flag包解析命令行输入的参数 flag.String("i", "infile", "1")
掌握os io bufio strconv等标准库的使用。
第三章 面向对象编程
支持为任意类型增加方法
type Integer int
func (a Integer) less (b Integer){
return a<b
}
Go语言的大多数类型都是值类型,包括基本类型和符合类型
slice map channel和interface看起来像引用类型。
结构体定义
type Rect struct {
x,y int
}
初始化 rect1 = new (Rect);rect2=&Rect{};rect3=&Rect{1,2};rect4=&Rect{x:1,y:2}
结构体通过匿名组合的方式,实现了类似java继承和方法覆盖的能力,如果方法没有被改写,则可以直接集成过来。
普通的struct不能赋值为nil,并且不能和nil进行==判断,struct指针可以赋值为nil,即使==nil,println也可以输出struct的类型。
非侵入式接口
type IFile interface {
Read (buf []byte)(n int, err error)
}
接口赋值
var a Integer = 1
var b LessAdder = &a
判断某个实例是否实现了接口
var file1 Writer = ...
if file6,ok:= file1.(*File);ok {
}
switch v := v1.(type) {
case int :
...
}
也可以通过反射的方式reflect.TypeOf()
接口跟结构体一样,支持匿名组合
空接口interface{}可以看做是可以指向任意对象的Any类型
接口对象和接口对象的指针都可以赋值为nil或者判断是否相等。
讲一个指针对象赋值为nil,然后将指针对象赋值给一个接口,此时接口对象不为nil,原因??
第四章 并发编程
常见的并发通信模型:共享数据、消息
线程和进程通过最多不超过1W个,而协程可以轻松创建上百万个。
goroutine支持的协程,在系统调用操作中会出让CPU给其他的goroutine。
channel:在多个goroutine之间传递消息,实现了锁的能力。
声明 var chanName chan ElementType ;var m map[string] chan bool
赋值 ch:=make (chan int)
写入 cha <- chanValue 写入会导致程序阻塞,直到有其他goroutine从该channel中读取数据
读取 chanValue :=<- ch,如果之前未写入数据,则读取也会导致程序阻塞。
select语句
for {
select {
case ch<-0:
case ch<-1:
}
i:= <-ch
}
带缓冲的channel,在channel缓冲区塞满之前不会阻塞
var c = make (chan int ,1024)
单向channel,可以限制只读或者只写
关闭channel cloes(chan)
判断一个channel是否被关闭 x,ok:=<-ch ok如果返回false,则代表chan已经被关闭。
多核并行化:需要使用runtime.GOMAXPROCS(16)来明确告诉GO编译器CPU的核数。 NumCPU()方法获取CPU核心数
出让时间片: Gosched()
同步锁:sync.Mutex和sync.RWMutex(单写多读)
全局唯一性操作 Once.Do() 在sync.Once包
第五章 网络编程
建立链接
conn,err:=net.Dial("tcp","192.168.0.10:2100") ==net.DialTCP
conn,err:=net.Dial("udp","192.168.0.10:2100") ==net.DialUDP
conn,err:=net.Dial("ip4:icmp","www.baidu.com")
conn,err:=net.Dial("ip4:icmp","www.baidu.com")
conn.write()
conn.read()
net.ResolveTCPAddr() 解析地址和端口号
net.ParseIP() 验证IP地址有效性
net.IPv4Mask 创建子网掩码
net.DefaultMask()
net.ResolveIPAddr()/net.LookupHost() 根据域名查找IP地址
http封装
http.Get("www.baidu.com")
http.Post()
服务端 http.ListenAndServe()
支持RPC编程
Go的默认数据结构编解码是用Gob,支持自定义