Go语言基础
一、简介
(1)什么是go语言?
2007年,受够了C++煎熬的Google首席软件工程师Rob Pike纠集Robert Griesemer和Ken Thompson两位牛人,决定创造一种新语言来取代C++, 这就是Golang。出现在21世纪的GO语言,虽然不能如愿对C++取而代之,但是其近C的执行性能和近解析型语言的开发效率以及近乎于完美的编译速度,已经风靡全球。特别是在云项目中,大部分都使用了Golang来开发,不得不说,Golang早已深入人心。而对于一个没有历史负担的新项目,Golang或许就是个不二的选择。
被称为GO语言之父的Rob Pike说,你是否同意GO语言,取决于你是认可少就是多,还是少就是少(Less is more or less is less)。Rob Pike以一种非常朴素的方式,概括了GO语言的整个设计哲学–将简单、实用体现得淋漓尽致。
很多人将GO语言称为21世纪的C语言,因为GO不仅拥有C的简洁和性能,而且还很好的提供了21世纪互联网环境下服务端开发的各种实用特性,让开发者在语言级别就可以方便的得到自己想要的东西。
1.1、发展历史
2007年9月,Rob Pike在Google分布式编译平台上进行C++编译,在漫长的等待过程中,他和Robert Griesemer探讨了程序设计语言的一些关键性问题,他们认为,简化编程语言相比于在臃肿的语言上不断增加新特性,会是更大的进步。随后他们在编译结束之前说服了身边的Ken Thompson,觉得有必要为此做一些事情。几天后,他们发起了一个叫Golang的项目,将它作为自由时间的实验项目。
2008年5月 Google发现了GO语言的巨大潜力,得到了Google的全力支持,这些人开始全职投入GO语言的设计和开发。
2009年11月 GO语言第一个版本发布。2012年3月 第一个正式版本Go1.0发布。
2015年8月 go1.5发布,这个版本被认为是历史性的。完全移除C语言部分,使用GO编译GO,少量代码使用汇编实现。另外,他们请来了内存管理方面的权威专家Rick Hudson,对GC进行了重新设计,支持并发GC,解决了一直以来广为诟病的GC时延(STW)问题。并且在此后的版本中,又对GC做了更进一步的优化。到go1.8时,相同业务场景下的GC时延已经可以从go1.1的数秒,控制在1ms以内。GC问题的解决,可以说GO语言在服务端开发方面,几乎抹平了所有的弱点。
在GO语言的版本迭代过程中,语言特性基本上没有太大的变化,基本上维持在GO1.1的基准上,并且官方承诺,新版本对老版本下开发的代码完全兼容。事实上,GO开发团队在新增语言特性上显得非常谨慎,而在稳定性、编译速度、执行效率以及GC性能等方面进行了持续不断的优化。
1.2、go语言的优缺点
参考博客:https://blog.csdn.net/QcloudCommunity/article/details/80735770
(2)golang语言特性
2.1. 垃圾回收
- 内存自动回收,再也不需要开发人员管理内存
- 开发人员专注业务实现,降低了心智负担
- 只需要new分配内存,不需要释放
2.2. goroute天然并发
- 从语言层面支持并发,非常简单
使用一个
go
则在编译时会自动开启一个线程来执行后面的命令/函数/方法,不用像python需要先调用thread模块来开启线程- goroute,轻量级线程,创建成千上万个goroute成为可能
- 基于CSP(Communicating Sequential Process)模型实现
2.3. goroute线程之间的数据通信——管道
使用go可以创建一个轻量级的goroute线程,线程之间如何通信,共享数据呢?答案是:使用管道来进行通信。管道需要定义并创建后,才能使用
定义一个管道:
var my_pipe chan int //my_pipe为管道名,chan为管道关键字表示定义的是一个管道,int表示管道内存储的数据类型
创建一个管道:
my_pipe = make(chan int,10) //make关键字表示开辟一个内存空间,第一个参数表示创建一个管道,10表示管道能存储的数据类型个数,如果超出则阻塞
定义和创建可以合并写
my_pipe := make(chan int,10)
管道的定义和使用范例:
//goroute线程之间使用管道进行数据通信 func main() { go pi_pie() } func pi_pie() { pipe := make(chan int, 10) //make关键字创建一个管道(关键字chan),管道内装int类型的数据,并且管道大小能装10个数字,超过则阻塞 pipe <- 10 //向管道内放入数据 pipe <- 9 pipe <- 9 pipe <- 7 pipe <- 6 var p1 int p1 = <-pipe //从管道取出数据 fmt.Println(p1) fmt.Println(len(pipe)) }
2.4. 多返回值
go的函数可以有多个返回值
“`
func main() {
x,y:=p_fun(10,80)
// x,_ := p_fun(10,80) 多返回值函数时,只要一个返回值
fmt.Println(x,y)
}//多返回值函数
func p_fun(a int,b int) (int,int) { //函数传入2个整型参数,返回2个值,都为int类型
sum := a+b
avg := (a+b)/2
return sum,avg
}2.5. go的“包”的概念
- 1.和python一样,把相同功能的代码放到一个目录,称之为包
- 2.包可以被其他包引用
- 3.main包是用来生成可执行文件,每个程序只有一个main包
- 4.包的主要用途是提高代码的可复用性
- 5.包的引用
go在首行使用“
package <包名>
”来声明自己所在的包(主程序包为main包,也可以自定义包名),“import”引入其他的包,go自带的系统包所在的路径已经在“GOROOT”环境变量中设置好了
可以使用“import”直接引入,而自己定义的包:package <包名>
在import导入时则需要相对路径:第三方包默认在“GOROOT”和“GOPATH”环境变量所在的路径下的src目录下寻找
Go的package不支持使用“../”方式的相对路径,都是从$GOPATH/src下一层一层找的
2.6. go文件编码规范
使用
gofmt <go文件>