https://www.jianshu.com/p/de26de7ca907
Go语言是Google公司开发的一种静态的,编译型并自带垃圾回收和并发的变成语言.
Go语言的风格类似C语言,其语法在C语言的基础上进行了大幅度的优化,去掉了不需要的表达式括号,循环也只有for一种表示方法,就可以实现数值,键值等各种遍历.因此, Go语言上手非常容易.
Go语言最具有特色的特性莫过于goroutine. Go语言在语言层可以通过goroutine对函数实现并发并行. goroutine类似于线程,但并非线程, goroutine会在Go语言运行时进行自动调度.因此,Go语言非常适合用于高并发网络服务的编写.
1.上手容易
例如实现一个简单的HTTP服务器只需要几行代码
import ( "net/http" ) func main() { http.Handle("/", http.FileServer(http.Dir("."))) http.ListenAndServe(":8080", nil) }
2.编译输出可执行文件
import "fmt" func main() { fmt.Println("hello world") }
将这段代码保存为main.go,确认安装了Go语言的开发包,使用如下指令可以将这段代码编译为可执行文件:
go build ./helloworld.go
执行hello world的可执行文件就可以输出"hello world"
Go语言不仅可以输出可执行文件,还可以编译输出导入C语言的静态库,动态库.
同时从Go1.7版本开始, Go语言支持将代码编译为插件. 使用插件可以动态加载需要的模块, 而不是一次性将所有的代码编译为一个可执行文件.
3.工程结构简单
Go语言的源码无需头文件,编译的文件都来自于后缀名为go的源码文件; Go语言无需解决方案,工程文件和Make File. 只要将工程文件按照GOPATH的规则进行填充,即可使用go build/go install 进行编译,编译安装的二进制可执行文件统一放在bin文件夹下.
4.编译速度快
Go语言可以利用自己的特性实现并发编译,并发编译的最小元素是包.从Go 1.9版本开始,最小并发编译元素缩小到函数,整体编译速度提高了20%.
另外, Go语言语法简单,具有严谨的工程结构设计,没有头文件卖不允许包的交叉依赖等规则,在很大程度上加速了编译的过程!
5.高性能
Go语言在性能上更接近Java语言,虽然在某些测试用例上不如经过多年优化的Java语言,但毕竟Java语言已经经历了多年的积累和优化. Go语言在未来的版本中会通过不断的版本优化提高单核运行性能.
6.原生支持并发
Go语言的特性就是从语言层支持并发,无需第三方库,开发者的编程技巧及开发经验就可以轻松地在Go语言运行时来帮助开发者决定怎么使用CPU资源.
Go语言的并发是基于goroutine, goroutine类似于线程,但并非线程.可以将goroutine理解为一种虚拟线程.Go语言运行时会参与调度goroutine,并将goroutine合理地分配到每个CPU中,最大限度地使用CPU性能.
多个goroutine中,Go语言使用通道(channel)进行通信,程序可以将需要并发的程序设计为生产者和消费者的模式,将数据放入通道.通道的另外一端的代码将这些数据进行并发计算并返回结果.
下面代码中的生产者每秒生成一个字符串,并通过通道传给消费者,生产者使用两个goroutine并发运行,消费者在main()函数的goroutine中进行处理
package main import ( "fmt"//导入格式化 "math/rand"//随机数 "time"//时间 ) //数据生产者 func producer(header string,channel chan <- string) {//生产数据的函数,传入一个标记类型为字符串及一个只能写入的通道 //无限循环,不停的生产数据 for { //将随机数和字符串格式化为字符串发送通道 channel <- fmt.Sprintf("%s:%v",header,rand.Int31()) //等待一秒 time.Sleep(time.Second) } } //数据消费者 func consumer(channel <- chan string) { //不停的获取数据 for { //从通道中取出数据,此处会阻塞直到信道中返回数据 message := <- channel //打印数据 fmt.Println(message) } } func main() { //创建一个字符串类型的通道 channel := make(chan string) //创建producer函数的并发goroutine(协成) go producer("cat",channel) go producer("dog",channel) //数据消费函数 consumer(channel) }
代码输出如下:
dog:140954425 cat:336122540 dog:208240456 cat:646203300 cat:1106410694 dog:1747278511 cat:817455089 dog:460128162 dog:683024728 cat:1006933274 cat:607811211 dog:629431445
整段代码中,没有线程创建,没有线程池也没有加锁,仅仅通过关键字Go实现goroutine,和通道实现数据交换.
7.性能分析
安装Go语言开发包后,使用Go语言开发工具链可以直接进行Go代码的性能分析. Go的性能分析工具将性能数据以二进制文件输出,配合Graphviz即可将性能分析数据以图形化的方式展现出来, Go语言会用过图连接和数据告知每个执行步骤的耗时,较为耗时的流程执行框会变大.开发人员会根据这些直观的图表即可迅速定位问题代码的位置!
8.强大的标准库
Go语言的标准库覆盖网络,系统,加密,编码,图形等各个方面,可以直接使用标准库的http包进行HTTP协议的收发处理;网络库基于高性能的操作系统通信模型(Linux的epoll,Windows的IOCP);所有的加密,编码都内建支持,不需要再从第三方开发者处获取.Go语言的编译器也是标准库的一部分,通过词法器扫描源码,使用语法树获得源码逻辑分支等.Go语言的周边工具也是建立在这些标准库上.在标准库上可以完成几乎大部分的需求.另外,Go语言的标准库以包的方式提供支持!
9.代码风格清晰,简单
Go语言写起来类似C语言,因此获悉C语言及其派生语言(C++,C#,Objective-C等)的人都会迅速熟悉这门语言.
C语言的一些语法会让代码可读性降低甚至发生歧义.Go语言在C语言的基础上取其精华,弃其糟粕,将C语言中较为容易发生错误的写法进行调整,做出相应的的编译提示.
1.去掉循环冗余括号
C语言
for (int a =0;a<10;a++) { //循环代码 }
Go语言
for a:= 0; a<10;a++ { //循环代码 }
2.去掉表达式冗余括号
C语言判断句
if(表达式){ //表达式成立 }
Go语言判断句
if 表达式{ //表达式成立 }
3.强制的代码风格
Go语言中,左括号必须紧接着语句不换行.其他样式的括号将被视为代码编译错误.这个特性刚开始会使一些开发者有以下不习惯,但随着对Go语言的不断熟悉,开发者就会发现风格统一让大家在阅读代码时会把注意力集中到解决问题上,而不是代码风格上.
同时Go语言也提供了一套格式化工具.一些Go语言的开发环境或者编译器在保存时,都会使用格式化工具进行修改代码格式化,让代码提交时已经统一格式的代码.
4.不在纠结于i++和++i
C语言非常经典的考试题为:
int a, b; a = i++; b = ++i
这种题目对于初学者兼职摸不着头脑.为什么一个简单的自增表达式需要有两种写法?
在Go语言中,自增操作符不再是一个操作符,而是一个语句.因此,在Go语言中自增只有一种写法:
i++
如果写成前置自增"++i",或者赋值后自增"a=i++"都将导致编译错误!
后续会继续更新~~~