go 简介与包
简介
安装配置
1 根据操作系统选择不同的安装包
下载地址 https://golang.org/dl/
2 安装
根据不同的安装包有不同的安装方法,具体参考官网
3 设置环境变量
需要设置go的环境变量
1)go 的执行文件路径(GOROOT)加到系统的PATH环境变量中
2)工作目录的路径,设置GOPATH环境变量
4 Hello world sample
1 // test 2 package main 3 4 import ( 5 "fmt" 6 ) 7 8 func add(a int, b int) int { 9 var sum int 10 sum = a + b 11 return sum 12 } 13 14 func main() { 15 16 var add_res int 17 add_res = add(100, 200) 18 fmt.Println("Hello World!", add_res) 19 }
golang 语言特性
1 垃圾回收
内存自动回收,不需要人为管理内存
只需要new 分配内存,不需要释放
2 天然并发(CPU多核)
从语言层面支持并发,简单
goroute,轻量级线程(个人感觉类似python中的协程),管理底层的无力线程
基于CSP(Communicating Sequential Process)实现,在go中主要是channel和goroute,简介如下
Channel Golang中使用 CSP中 channel 这个概念。channel 是被单独创建并且可以在进程之间传递,它的通信模式类似于 boss-worker 模式的,一个实体通过将消息发送到channel 中,然后又监听这个 channel 的实体处理,两个实体之间是匿名的,这个就实现实体中间的解耦,其中 channel 是同步的一个消息被发送到 channel 中,最终是一定要被另外的实体消费掉的,在实现原理上其实是一个阻塞的消息队列。 Goroutine Goroutine 是实际并发执行的实体,它底层是使用协程(coroutine)实现并发,coroutine是一种运行在用户态的用户线程,类似于 greenthread,go底层选择使用coroutine的出发点是因为,它具有以下特点: 用户空间 避免了内核态和用户态的切换导致的成本 可以由语言和框架层进行调度 更小的栈空间允许创建大量的实例 可以看到第二条 用户空间线程的调度不是由操作系统来完成的,像在java 1.3中使用的greenthread的是由JVM统一调度的(后java已经改为内核线程),还有在ruby中的fiber(半协程) 是需要在重新中自己进行调度的,而goroutine是在golang层面提供了调度器,并且对网络IO库进行了封装,屏蔽了复杂的细节,对外提供统一的语法关键字支持,简化了并发程序编写的成本。
1 // test 2 package main 3 4 import ( 5 "time" 6 ) 7 8 func add(a int, b int) int { 9 var sum int 10 sum = a + b 11 return sum 12 } 13 14 func main() { 15 16 //var add_res int 17 //add_res = add(100, 200) 18 //go test_goroute(10, 20) 19 //fmt.Println("Hello World!", add_res) 20 21 for i := 0; i < 100; i++ { 22 go test_print(i) 23 } 24 time.Sleep(5) 25 }
3 channel
管道,类似unix/linux中的pipe
多个goroute之间通过channel进行通信
支持任何类型
1 // pipe 2 package main 3 4 import ( 5 "fmt" 6 ) 7 8 func test_pipe() { 9 pipe := make(chan int, 3) 10 pipe <- 1 11 pipe <- 2 12 pipe <- 3 13 fmt.Println(len(pipe)) 14 }
4 goroute和pipe的sample
1 // sub 2 package calc 3 4 func Sub(a int, b int, c chan int) { 5 c <- (a - b) 6 }
1 // add 2 package calc 3 4 func Add(a int, b int, c chan int) { 5 c <- (a + b) 6 }
1 // calculator 2 package main 3 4 import ( 5 "day1/calc" 6 "fmt" 7 ) 8 9 func main() { 10 var pipe chan int 11 pipe = make(chan int, 1) 12 go calc.Add(100, 200, pipe) 13 go calc.Sub(100, 200, pipe) 14 sum := <-pipe 15 sub := <-pipe 16 fmt.Println(sum, sub) 17 }
包
1 和python一样,把相同功能的代码放到一个目录,称之为包
2 包可以被其他包引用
3 main包是用来生成可执行文件,每个程序只能有一个main包
4 包主要的用途是提高代码的可复用性
5 一般go项目路径说明
/project/src/ 源文件
bin/ 可执行文件
vendor/ 第三方文件
pkg/ 静态库
6 Go中如果函数名的首字母大写,表示该函数是公有的,可以被其他程序调用,如果首字母小写,该函数就是是私有的,因此我们只能调用其他包文件中的公有函数
7 包的别名
import ( f "fmt" ) func main() { n := 10 for i := 0; i <= n; i++ { f.Printf("%d+%d=%d\n", i, n-i, n) } }
8 每个源文件都可以包含一个init函数,这个init函数自动被go运行框架调用
// main package main import ( "fmt" ) func init() { fmt.Println("----initiation----") }
9 只初始化包,并不引用
// main package main import ( _ "path/external_func" ) func init() { fmt.Println("----initiation----") }