Go语言开发初探
2015-12-24 00:00
901 查看
摘要: Go语言弥补了C语言的不足并且保持了C的极简主义,专门针对多处理器系统编程进行了优化,使用Go语言除大幅度提升开发速度外,编译的程序还可媲美C或C++代码的速度,因此,可以将Go作为第一个学习的开发语言。
背景:Go语言是Google公司2009年推出的一种全新的静态编译型语言,目标是取代C、C++、Java作为系统开发的语言,经历了6年6次更新之后,最新版本为1.5,整个系统除一小部分由汇编完成外,其余都采用Go语言编写,语言日趋成熟。据笔者了解,国内知名IT公司如阿里、360、京东、小米、搜狗等都在积极尝试和使用,尤其是七牛云储存(http://qiniu.com)使用Go语言的比例为99.9%。多核和集群是互联网时代的典型特征,Go语言专门针对多处理器系统进行了优化,能更好的发挥多核性能,更安全高效的进行并发操作,因此,笔者决定尝试使用Go语言。 摘要:Go语言弥补了C语言的不足并且保持了C的极简主义,专门针对多处理器系统编程进行了优化,使用Go语言除大幅度提升开发速度外,编译的程序还可媲美C或C++代码的速度,因此,可以将Go作为第一个学习的开发语言。
关键词:Go,编程,并发,多核,网络
一、了解Go语言
按照Google公司Go语言创始人的话来说:我们之所以开发Go,是因为过去10多年间软件开发的难度令人沮丧。Go语言的开发效率不差于如Python等动态语言,同时又具备接近甚至达到C语言的执行效率。以下是笔者认为Go语言比较突出的几个优点:
1.跨平台支持,部署简单。Go语言可以在多个平台上进行编译,编译生成的是一个静态可执行文件,除了glibc外没有其他外部依赖,支持主流的32位和64位的x86平台,也支持32位的ARM架构,同时支持多种操作系统,不需要针对系统环境做额外的部署。
2.语言级别的原生并发机制。并发编程一直以来都是个非常困难的工作,但Go语言从语言层面上支持了并发,而这个也成为Go语言很重要的一个特性,在Go中并发程序依靠的是:goroutine(类似于线程)和channel。
3.高开发效率和高性能。Go语言语法简洁,开发效率可以和Python、Ruby等动态语言媲美,有完全的内存垃圾回收机制,最新的Go 1.5在程序的执行效率上已能达到C语言。
二、开发实战
(一)开发环境介绍
Go语言下载地址为:https://golang.org/dl/。
本次开发环境直接部署在Windows平台(win 10 10586版),最新Go语言版本为1.5.1,编译器使用的是较为流行的Sublime Text 3 + Gosublime ,当然还有一些辅助插件如:ConvertToUTF8,Alignment等,解决中文和代码对齐等功能。安装完成后可以通过在命令行输入go version查看是否安装成功。
环境配置好以后,首先通过一个Hello World,验证开发环境是否能成功运行:
(二)Go语言基础
1.Go语言中,声明变量时使用var关键字(类似JavaScript),变量的声明和定义有以下几种形式:
Go语言中进行变量申明时,如果不使用var关键字,可以使用更为简洁的:=符号,但需要注意的是var和:=不能同时使用。
Go语言中,如果一个变量没有被用到,GO的编译会报错,未使用引入的包也会报错。
2.Go语言所支持的一些常用基本数据类型如下:
在Go语言中,还有几个基本数据类型:byte、rune、int、uint、uintptr,其中byte类似uint8,rane类似int32,uint和int都是根据平台而定,一般为32位或者64位,而uintptr表示的是无符号整形,用于存放一个指针。
3.在Go语言中,if、while、for后面的条件表达式都没有小括号,而且第一个大括号不能换行,否则会报错,其实这一点习惯后也没有觉得有什么问题。
(三)Go语言特性探究
1.首先,写一个简单的Go程序,以便对Go语言有个更全面的认识,具体代码如下:
运行程序后如下图(每次执行都会生成10个随机乱序数列):
在这段程序中,我们实现了Go语言版的冒泡排序,程序每次运行的时候,都是随机生成一个乱序的数列,然后再进行排序。在这里,我们可以看到if条件判断、for循环、整形数组等使用方式和语法。总的来看,还是比较简单。
2.多参数返回。在下面这段代码中,我们很简单快捷的实现了函数返回两个值。
3.Go语言接口编程。接口是Go语言中所有数据接口的核心,Go语言的主要设计者之一罗布.派克曾经说过,如果只能选择一个Go语言的特性移植到其他语言中,他会选择接口。在Go语言中,接口就是一大堆方法的集合。下面是一个Go语言官方关于接口的例子:
在这个例子里,首先定义了一个关于几何图形的接口,作为例子,只包含了计算面积和周长的两个方法,下图是执行后的结果。
实现接口很简单,定义任意一个几何形状后,只要有area()和perim()这两个方法,就算是实现了上面的接口。例如我们想增加对三角形面积的计算,可以增加如下代码:
因为实现了geometry这个接口的两个方法:area和perim,因此我们可以直接调用measure来查看输出结果:
4.Go语言并发编程。在学习Go语言并发编程的时候,我们会学习两个新的感念,goroutine和channel。其中goroutine类似开辟一个新的线程,但是比线程还小,而且不受操作系统调度,用法极其简单(有的时候,越简单的东西,越容易让人犯糊涂),就是在调用的函数前加一个关键字“go”如:
举个例子,手头有一堆数据,需要经过超级复杂,超级耗时的计算才能得出答案。显然我们的主routine不可能只干这一件事,它还有其他事情需要处理。因此,我们开辟一个routine让其自个算去,而主程序将会继续执行。这里我们会发现,如果分配的routine计算出答案,如何回传给主routine使用呢?这时,channel就发挥应有的作用了。
Go语言使用channel接收或者发送特定类型的值,可以自己根据实际情况指定,比如两个routine之间相互传值为int类型,那么channel类型就可以设定为chan int,并且可以灵活的设置通道缓冲数据大小。
下面来看一个具体例子:
这个是程序执行后结果:
如果在子routine执行的时候,主程序继续做别的事情,会是什么情况?
当然,这只是Go语言中并发编程最基础的用法实例,更多高级应用还需要继续深入学习。
四、总结
Go语言已经发布6年多,这几年,移动互联网飞速发展,Go语言也不断成长,并渐渐被各大公司认可。通过这次初探,我们也可以大概领略到Go语言的魅力,我认为可以利用这样一句广告语来概括:“简约但不简单”。是的,随着学习的深入,越来越发现Go语言的强大。
参考资料:
1.Https://gobyexample.com
2.许式伟 吕桂华.《Go语言编程》 人民邮电出版社
3.Rob Pike 《并发不是并行》
背景:Go语言是Google公司2009年推出的一种全新的静态编译型语言,目标是取代C、C++、Java作为系统开发的语言,经历了6年6次更新之后,最新版本为1.5,整个系统除一小部分由汇编完成外,其余都采用Go语言编写,语言日趋成熟。据笔者了解,国内知名IT公司如阿里、360、京东、小米、搜狗等都在积极尝试和使用,尤其是七牛云储存(http://qiniu.com)使用Go语言的比例为99.9%。多核和集群是互联网时代的典型特征,Go语言专门针对多处理器系统进行了优化,能更好的发挥多核性能,更安全高效的进行并发操作,因此,笔者决定尝试使用Go语言。 摘要:Go语言弥补了C语言的不足并且保持了C的极简主义,专门针对多处理器系统编程进行了优化,使用Go语言除大幅度提升开发速度外,编译的程序还可媲美C或C++代码的速度,因此,可以将Go作为第一个学习的开发语言。
关键词:Go,编程,并发,多核,网络
一、了解Go语言
按照Google公司Go语言创始人的话来说:我们之所以开发Go,是因为过去10多年间软件开发的难度令人沮丧。Go语言的开发效率不差于如Python等动态语言,同时又具备接近甚至达到C语言的执行效率。以下是笔者认为Go语言比较突出的几个优点:
1.跨平台支持,部署简单。Go语言可以在多个平台上进行编译,编译生成的是一个静态可执行文件,除了glibc外没有其他外部依赖,支持主流的32位和64位的x86平台,也支持32位的ARM架构,同时支持多种操作系统,不需要针对系统环境做额外的部署。
2.语言级别的原生并发机制。并发编程一直以来都是个非常困难的工作,但Go语言从语言层面上支持了并发,而这个也成为Go语言很重要的一个特性,在Go中并发程序依靠的是:goroutine(类似于线程)和channel。
3.高开发效率和高性能。Go语言语法简洁,开发效率可以和Python、Ruby等动态语言媲美,有完全的内存垃圾回收机制,最新的Go 1.5在程序的执行效率上已能达到C语言。
二、开发实战
(一)开发环境介绍
Go语言下载地址为:https://golang.org/dl/。
本次开发环境直接部署在Windows平台(win 10 10586版),最新Go语言版本为1.5.1,编译器使用的是较为流行的Sublime Text 3 + Gosublime ,当然还有一些辅助插件如:ConvertToUTF8,Alignment等,解决中文和代码对齐等功能。安装完成后可以通过在命令行输入go version查看是否安装成功。
环境配置好以后,首先通过一个Hello World,验证开发环境是否能成功运行:
(二)Go语言基础
1.Go语言中,声明变量时使用var关键字(类似JavaScript),变量的声明和定义有以下几种形式:
Go语言中进行变量申明时,如果不使用var关键字,可以使用更为简洁的:=符号,但需要注意的是var和:=不能同时使用。
Go语言中,如果一个变量没有被用到,GO的编译会报错,未使用引入的包也会报错。
2.Go语言所支持的一些常用基本数据类型如下:
类型 | 范围 |
bool | true,false |
int8 | -128 - 127 |
int16 | -32768- 32767 |
int32 | -2147483648-2147483647 |
int64 | -9223372036854775808-9223372036854775807 |
uint8 | 0-255 |
uint16 | 0-65535 |
uint32 | 0-4294967295 |
uint64 | 0-188446744073709551615 |
string | |
float32 | IEEE-754 32位浮点型数 |
float64 | IEEE-754 64位浮点型数 |
3.在Go语言中,if、while、for后面的条件表达式都没有小括号,而且第一个大括号不能换行,否则会报错,其实这一点习惯后也没有觉得有什么问题。
for j := 0; j < len(l); j++ { if i == l[j] { r = true } }
(三)Go语言特性探究
1.首先,写一个简单的Go程序,以便对Go语言有个更全面的认识,具体代码如下:
package main
import "fmt"
import "math/rand"
import "time"
//定义生成随机列表的大小
const MAXLEN = 10
//定义随机数生成范围
const MAXNUM = 100
//Go语言版冒泡排序
func bubblesort(intList []int, length int) {
if length > 1 {
for i := 0; i < length-1; i++ {
if intList[i] > intList[i+1] {
intList[i], intList[i+1] = intList[i+1], intList[i]
}
}
bubblesort(intList, length-1)
}
}
//确保生成的列表中没有重复数
func isExists(l []int, i int) bool {
r := false
for j := 0; j < len(l); j++ { if i == l[j] { r = true } }
return r
}
//生成乱序整数列表
func makeList() []int {
var intList []int
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; len(intList) < MAXLEN; i++ {
tmp := r.Intn(MAXNUM)
if !isExists(intList, tmp) {
intList = append(intList, tmp)
}
}
return intList
}
func main() {
//随机生成一个乱序的整数列表
intList := makeList()
fmt.Println("随机生成的乱序整数列表为:", intList)
bubblesort(intList, len(intList))
fmt.Println("乱序列表经过冒泡排序后:", intList)
}
运行程序后如下图(每次执行都会生成10个随机乱序数列):
在这段程序中,我们实现了Go语言版的冒泡排序,程序每次运行的时候,都是随机生成一个乱序的数列,然后再进行排序。在这里,我们可以看到if条件判断、for循环、整形数组等使用方式和语法。总的来看,还是比较简单。
2.多参数返回。在下面这段代码中,我们很简单快捷的实现了函数返回两个值。
3.Go语言接口编程。接口是Go语言中所有数据接口的核心,Go语言的主要设计者之一罗布.派克曾经说过,如果只能选择一个Go语言的特性移植到其他语言中,他会选择接口。在Go语言中,接口就是一大堆方法的集合。下面是一个Go语言官方关于接口的例子:
package main import ( "fmt" "math" ) //定义一个简单的几何图形的接口 type geometry interface { area() float64 //面积 perim() float64 //周长 } //定义一个长方形 type rect struct { width, height float64 } //定义一个圆形 type circle struct { radius float64 //半径 } //计算长方形面积 func (r rect) area() float64 { return r.width * r.height } //计算长方形周长 func (r rect) perim() float64 { return 2*r.width + 2*r.height } //计算圆形面积 func (c circle) area() float64 { return math.Pi * c.radius * c.radius } //计算圆形周长 func (c circle) perim() float64 { return 2 * math.Pi * c.radius } func measure(g geometry) { fmt.Println(g) fmt.Println("面积:", g.area()) fmt.Println("周长:", g.perim()) } func main() { r := rect{width: 3, height: 4} c := circle{radius: 5} measure(r) measure(c) }
在这个例子里,首先定义了一个关于几何图形的接口,作为例子,只包含了计算面积和周长的两个方法,下图是执行后的结果。
实现接口很简单,定义任意一个几何形状后,只要有area()和perim()这两个方法,就算是实现了上面的接口。例如我们想增加对三角形面积的计算,可以增加如下代码:
//定义三角形 type triangle struct { side1, side2, side3 float64 } //通过海伦公式计算三角形面积 func (t triangle) area() float64 { hp := (t.side1 + t.side2 + t.side3) / 2 return math.Sqrt(hp * (hp - t.side1)(hp-t.side2)(hp-t.side3)) } //计算三角形周长 func (t triangle) perim() float64 { return t.side1 + t.side2 + t.side3 }
因为实现了geometry这个接口的两个方法:area和perim,因此我们可以直接调用measure来查看输出结果:
4.Go语言并发编程。在学习Go语言并发编程的时候,我们会学习两个新的感念,goroutine和channel。其中goroutine类似开辟一个新的线程,但是比线程还小,而且不受操作系统调度,用法极其简单(有的时候,越简单的东西,越容易让人犯糊涂),就是在调用的函数前加一个关键字“go”如:
func sayhello(){ //do something } go sayhello() //添加关键字go后,函数sayhello就作为goroutine去执行
举个例子,手头有一堆数据,需要经过超级复杂,超级耗时的计算才能得出答案。显然我们的主routine不可能只干这一件事,它还有其他事情需要处理。因此,我们开辟一个routine让其自个算去,而主程序将会继续执行。这里我们会发现,如果分配的routine计算出答案,如何回传给主routine使用呢?这时,channel就发挥应有的作用了。
Go语言使用channel接收或者发送特定类型的值,可以自己根据实际情况指定,比如两个routine之间相互传值为int类型,那么channel类型就可以设定为chan int,并且可以灵活的设置通道缓冲数据大小。
//通过make创建一个int类型channel var c = make(chan int) //或者不使用关键字 c1 := make(chan bool) //向channel c 写入数据 c<-1 //从channel c中读取数据 <-c
下面来看一个具体例子:
这个是程序执行后结果:
如果在子routine执行的时候,主程序继续做别的事情,会是什么情况?
当然,这只是Go语言中并发编程最基础的用法实例,更多高级应用还需要继续深入学习。
四、总结
Go语言已经发布6年多,这几年,移动互联网飞速发展,Go语言也不断成长,并渐渐被各大公司认可。通过这次初探,我们也可以大概领略到Go语言的魅力,我认为可以利用这样一句广告语来概括:“简约但不简单”。是的,随着学习的深入,越来越发现Go语言的强大。
参考资料:
1.Https://gobyexample.com
2.许式伟 吕桂华.《Go语言编程》 人民邮电出版社
3.Rob Pike 《并发不是并行》
相关文章推荐
- pymongo带认证连接mongo
- Sunday算法---简单高效的字符串匹配算法
- CF #GoodBye 2014 A~E
- golang学习之go简单博客应用
- Zygote的启动过程
- 流程控制与数组(goto语句)
- 【AC自动机+DP】[USACO JAN2012 GOLD Problem 1: Video Game Combos]
- 用pycharm+django开发web项目
- Django之路: 基本命令与网址进阶
- DJANGO:从当前用户的所属用户组里查找其所拥有的权限矩阵
- Highcharts xAxis events事件 categories动态取值
- DragonBoard410c 控制LED实验
- Django知识点总结(四)
- 类别(Categories)和扩展/匿名类别(extensions)及其延伸使用
- django常用函数
- Spark on Yarn: Where Have All the Memory Gone?
- 初识GoAhead
- beego 如何自定error
- 例题8-5 UVA 11054 Gergovia的酒交易
- goto语句的替换方法--用while