Go语言的前世今生
Hello,大家好呀,谢谢你们的到来,我是今天的主角——Go
Go语言的诞生历程
2007年9月,谷歌实验室里,61岁的Rob Pike(罗伯.派克),74岁的Ken Thompson(肯.汤普森)和64岁的Robert Griesemer(罗伯特.格利茨默) 三位工程师聚在了一块,给我取了个简洁的名字——Go.
他们亦父亦母,又是老来得子,所以我一直是“集万千宠爱于一身”。又因为他们三个都很厉害,有 B 语言、C 语言以及Unix之父,且获取了图灵奖和美国国家技术奖的 Ken,有 UTF-8 字元编码的创作人 Rob,还有Google V8、HotSpot JVM的主要贡献者。因此,我还被很多人称为 “牛二代”。
2009年11月10日是我的生日,我之前的作品都在 Google 的 codehub 里被托管,后来用的人多起来,所以代码又慢慢迁移到了 GitHub. 在国内也慢慢风靡起来,给大家看看我涉及的业务范围:
除Docker容器、kubernetes(业内人称k8s) 等大型项目完全用 Go 语言实现外,越来越多的互联网大厂都在向 Go 转型。如今,云计算领域和很多大型项目的微服务开发中,Go语言已经取得了至关重要的地位。
为什么Go 语言会风靡全球
-
首先,我是一门编译型语言,相同的程序,我的执行速度要比 Java 等解释性语言快30%~70%;
-
其次,作为 21 世纪的C语言,我的开发速度也不落下风,简洁高效的语法让 C 和 C++研发人员望尘莫及;
-
并发支持友好,一行代码就能实现并发的优势会让我在高并发场景中越来越受欢迎;
-
最后,云计算时代的到来,互联网服务器的大量需求,会让我在未来大展身手,一展鸿图。
别问鸿图是啥,问就是超越 Java、python 等语言,跻身热门前列。
Go,面向对象?
很多刚接触我的伙伴都很疑惑,我支持封装,但不支持继承和多态,严格来说我并不属于面向对象的语言。但是我支持接口(interface)去适用任何一种数据类型,并且允许面向对象的编程风格,从这个层面上我也是一种面对对象的语言。
那么,我到底是不是一种面向对象的语言呢?我们一起来看看官方文档怎么对我定义的:
答案:是也不是。一方面 Go 具备面向对象的编程风格,另一方面它不具备对象的继承方式,所以 Go 既是面向对象的语言,又不完全是。
而正是缺少对象的继承特性,使得 Go 语言比 C++/Java 更轻量简便。大家不妨想一想基类、派生类、单继承、多继承、权限控制等问题吧。
快速入门
1. hello, world 第一个Go程序
无论你是基于工作要求,还是想学好一门极具潜力的开发语言,又或者是第一次接触计算机与编程,都请跟着我一起进入Go语言的世界吧。
听了这么多的王婆卖瓜的故事,想必大家都对这种推崇的套路了然于胸了。所以,废话不多说。人生苦短,Let’s Go !
绝大多数计算机从业者人生中的第一个程序:
// 包名,main,特殊的包,用来定义一个独立的可执行程序
package main
import "fmt"
func main() {
fmt.Println("hello world!")
}
我和很多语言一样,main 函数都是第一个执行的函数,但是 main 包在 Go 语言里面比较特殊,是用来定义一个独立的可执行程序。简单来说,就是只要有 main 函数出现且需要运行这个 main 函数的地方,就一定要引入 main 包:
package main
fmt 包里面包含了一些标准的输出和输入函数,比如打印函数 Print,程序里的 Println 表示打印完之后立即换行。
还不会运行 Go 程序?先看看这篇 Go安装与配置运行
Go 语言提供两种常用的运行程序的方式:
-
用 go build 命令编译生成一个 .exe 文件,再执行
go build hello.go
这时,目录里会生成一个 .exe 编译型文件,我们可以直接在 Windows 机器上打开,也可在命令行或者 git bash 里执行生成的 .exe 文件
./hello.exe
-
直接用 go run 命令执行
go run hello.go
运行结果
hello world!
2. 找出一组字符串列表中的重复行
这个程序会让你学到 Go 里面常用的 for 循环方式,以及字符串切片的定义与使用(切片:可理解为是长度可变的数组):
package main
import "fmt"
func main() {
arr := []string{"qq", "wechat", "dnf", "lol", "wechat"}
counts := make(map[string]int)
for i := 0; i < len(arr); i++ {
counts[arr[i]]++
}
for key, value := range counts {
if n > 1 {
fmt.Printf("值为 %s 的字符串重复了%d次 \n", key, value)
}
}
}
定义一个字符串切片:arr := []string{},左边是变量名,:= 是 Go 语言里常用的赋值语句,比如:i := 0,就是先把 i 变量初始化之后再赋值,等同于:
var i int i = 0
在我 Go 语言的世界里,定义 map 一般是先用 make 初始化 map,防止空指针异常。或者新建时就定义一个带初始化键值对元素的 map:
counts := map[string]int {
"qq" : 1,
"wechat" : 2,
}
map [string] int,表明单个字符串 string 为键,字符串的数量 int 类型为值。
然后,再统计字符串列表中的各字符串数目,这里我们用了自增的方式 counts[arr[i]]++ 去统计字符串的数目,等同于:
counts[arr[i]] = counts[arr[i]] + 1
这种自增的好处是可以省去重复出现的变量,简洁代码。
最后,我们遍历打印出,出现次数大于1的字符串。
运行结果:
值为 wechat 的字符串重复了2次
for 是 go 里面的唯一循环方式,常见有两种形式:
for init; condition; post {
// 单或多个语句
}
for 循环的组成两边不用小括号,for 语句之后的大括号是必须的,且左大括号必须和 post (后置)语句在同一行
for i, v := range array {
// 单或多个语句
}
for range用来快速遍历具有多个元素的数据结构(数组,切片,map等),i 为元素的索引(取值范围 0~ len(array)-1),v 为元素的值。
即, v == array[i]
总结
此篇文章介绍了 Go 语言的历史及大致的应用场景,值得一提的是,分布式开发和微服务架构都还是处于较前沿的位置,如今很多程序猿都还在传统公司和小型计算机企业里,接触不到新技术和新项目。
所以我写 Go 这个系列,也是想让更多想学但没有途径和方向的计算机方向的在校人员,或者已经走上工作岗位的从业者能够真正地领悟到 Go 的魅力。在很多互联网大厂,如微软、字节、腾讯、金山、迅雷,包括华为这样的通信公司,在很多业务团队里都已经开始向 Go 转型,Go 也必将成为云计算时代最热门的开发语言!
趁着黎明还不明朗,趁着月亮还挂在天上,背着行囊,跟我一起出发吧!