Go 实战分享

—— Go 语言发展历程及学习实践

25 Jun 2018

Bingo Huang

自我介绍

预告下:2018 Gopher Meetup@杭州 要来了,7月8号(周日),去年老地方
2

目录

3

Go 发展起源

4

编程语言的历史与现状

- 单机时代
- C 语言独领风骚
- 成功原因:简单、对机器的绝佳抽象
- 互联网时代
- Java 语言异军突起
- 成功原因:机器性能的提升,软件规模与复杂度提高
- 可以说是云计算时代
- Go 语言已成为云计算领域事实上的标准语言
- 原因:Go 以 C 语言为原型,以降低心智负担为设计理念,大道至简 + 杀手级项目 Docker/Kubernetes(@CNCF)
5

Go 与云计算

大型主机时代,人们面对的是:体形庞大, 软硬件资源有限的大型机

人们需要一个高效率的操作系统去操作这些庞然大物, C 语言应运诞生
云计算时代,人们面对是:体形无比庞大, 软硬件资源无限的云

人们追求极致体验、 高可靠的移动互联网软件服务

Go 语言立志要成为云系统基础设施的核心语言, 被`教主许式伟`称为`21世纪的C语言`
6

Go 发展历程

- 创始者三剑客:Ken Thompson, Rob Pike 和 Robert Griesemer
- 而后加入的人:Russ Cox, Ian Lance Taylor, Brad Fitzpatrick, Andrew Gerrand 等
- Go 1   (3月  2012)
- Go 1.1 (5月  2013)
- Go 1.2 (12月 2013)
- Go 1.3 (6月  2014)
- Go 1.4 (12月 2014)
- Go 1.5 (8月  2015)
- Go 1.6 (2月  2016)
- Go 1.7 (8月  2016)
- Go 1.8 (2月  2017)
- Go 1.9 (8月  2017)
- Go 1.10 (2月  2018)
7

TIOBE 年度编程语言(2003-2017)

8

TIOBE Go语言走势图(2003-2017)

9

Go Team - 三个泰斗级的人物

- Unix之父, B语言、C语言的作者,1983年图灵奖得主
- Unix、UTF-8、plan9的作者,r@google.com,大名 Robert Pike
- Google V8、Chubby 和 HotSpot JVM 的主要贡献者,Go 规约设计者
10

Go Team - 几个独当一面的人物

- 参与Plan 9操作系统开发。Google Code Search 项目负责人,第4位 Go 语言提交者
- gcc 社区的活跃人物。gold连接器和gcc过程间优化LTO的主要设计者,Zembu公司的创始人。
- LiveJournal 创始人,著名开源项目 memcached 的作者
- 2010年2月加入Google和Go team,多次担任 Go 的发言人。澳大利亚人,本科专业摄影,艺术学位。
11

Go Team - “炉边谈话”

www.youtube.com/watch?v=sln-gJaURzk

www.youtube.com/watch?v=p9VUCp98ay4

www.youtube.com/watch?v=ynQoaajojIs

12

Go 的创立故事 - 程序员忙里偷闲的理由

13

Go 的创立故事

14

Go 最初的设计

- Robert:以C语言为原型,修补部分明显的缺陷,去掉垃圾功能,添加一些缺失的功能。

- Rob:命名为“Go”,好处有很多,这名字非常简短,容易拼写。工具可以叫做:goc、gol、goa。
  如果有可交互的调试器/解释器也可以简单地叫它“Go”,后缀名用.go。

- Robert:定义空接口语法:interface{}。所有接口都通过这个实现,因此可以用它代替void*。
15

Go 最初的代码提交

16

Go 语言起源影响

哪些早期的编程语言对Go语言的设计产生了重要影响
17

Go 的设计理念

开发者不应该在语法细节与技巧和工程管理等事情上消耗过多精力,而是更多专注解决业务问题。
如三目运算符,如泛型?
18

Go 语言特性

19

Go = C + Python

| 语言    年份  | 设计哲学                                           
| C      1972  | 简单而高效                                         
| C++    1980  | 精准控制,zero cost                               
| Python 1991  | 优雅胜于丑陋,明确胜于含糊,简单胜于复杂               
| Ruby   1993  | Ruby继承了Perl的设计哲学,提供处理同样事物的多种方法                        
| Java   1995  | 一次编译,到处运行. 一切皆对象
| Go     2009  | 少即是多,大道至简
20

说了这么多,上个代码吧

// +build OMIT

package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}
// +build OMIT

package main

func main() {
    ch := make(chan int)
    // 启动一个新的匿名 goroutine
    go func() {
        // 发送 42 给 channel
        ch <- 42
    }()
    // 从 channel 读取
    println(<-ch)
}
21

Go 关键字

Go(25),  Python(31),  C99(37),  Java(53), C#(79), C++11(84)
22

Go 关键字

分类:

- import, package
- chan, const, func, interface, map, struct, type, var
- go, select, break, case, continue, default, defer, else
- fallthrough, for, goto, if, range, return, switch
23

if-else

  func abs(value int) int {
    if value < 0 {
      return -value
    } else {
      return value
    }
  }
- if(else if) 后面表达式不需要括号,另外 { 必须与 if 在一行

- 能否简化为三目运算符?
- 如果这样做,将会在大括号的前方插入一个分号,这可能导致出现不想要的结果。
24

for-range

  sum := 0

  // 1. for
  for i := 0; i < 100; i++ {
      sum++
  }

  // 2. while
  for sum <= 100 {
    sum++
  }

  // 3. do while
  for {
    sum++
    if sum > 100 {
      break
    }
  }

  // 4. for range
  for index, value := range array {
      println(value)
  }
25

for-range

- { 同样必须与 for 在一行
- Go没有while语句,采用for实现
- Go没有do while语句,采用for实现
- for-range 相当于 java 中的 for-each, 但可同时返回数组下标
- arrays, slices, strings, maps and channels
26

switch-case

  switch i {
  case 1:
    fmt.Printf("1")
  case 2:
    fallthrough
  case 3:
    fmt.Printf("3")
  case 4, 5, 6:
    fmt.Printf("4, 5, 6")
  default:
    fmt.Printf("Default")
  }

  switch {
  case 0 <= Num && Num <= 3:
    fmt.Printf("0-3")
  case 4 <= Num && Num <= 6:
    fmt.Printf("4-6")
  default:
    fmt.Printf("Default")
  }
27

switch-case

- switch必须与 { 在一行

- 条件表达式不限制为常量或者整数

- switch后面可以没有表达式

- 单个case中,可以出现多个结果选项

- Go语言不需要用break来明确退出一个case

- 只有在case中明确添加fallthrough关键字,才会继续执行紧跟的下一个case
28

goto

  func gotodemo() {
    i := 0
  HERE: // Labels
    fmt.Println(i)
    i++
    if i < 10 {
      goto HERE
    }
  }
- 通常的程序结构有:顺序、选择、循环,此外,Go语言还有 goto 跳转结构

- Go语言这么珍惜关键字,竟然支持goto,看来goto也不是毫无价值的。
29

变量-var

  var a int = 1
  var b = 2

  c := a + b

  func add(d, e int) int {
    f := d + e
    return e
  }
- 类型后置

- 大多数时候变量类型能自动推导

- 除非是函数参数与返回值
30

类型-type

  type Integer int
type T1 T2  // 传统的type defintion

vs.

type T1 = T2 //新增的type alias
type  超级赛亚人 孙悟空
type  卡卡罗特 = 孙悟空
31

结构-struct

  type Rect struct {
    x, y          float64
    width, height float64
  }

  func (r *Rect) Area() float64 {
    return r.width * r.height
  }
- Go 没有构造函数,当然也没有析构函数

- Go 不支持 class 与继承, 唯一类型封装就是 struct,与 C 一样

- 可以为 struct 增加方法
32

函数-func

  func multiret() (int, error) {
    return 0, nil
  }

  func square(n int) int { return n * n }

  func cube(n int, f func(int) int) {
    return n * f(n)
  }

  func main() {
    f := cube
    fmt.Println(f(3, square))
  }
- 返回值声明在最后,可以返回多个参数

- 函数是一类公民,可以作为变量赋值,函数参数传递
33

方法-func

  type Integer int

  func (a Integer) Less(b Integer) bool {
    return a < b
  }

  func main() {
    var a Integer = 1
    if a.Less(2) {
      fmt.Println(a, "Less 2")
    }
  }
- 允许给已有的类型,第三方包的类型增加方法
34

匿名函数-func

// +build OMIT

package main

import "fmt"

func squares() func() int {
    var x int
    return func() int {
        x++
        return x * x
    }
}

func main() {
    f := squares()
    fmt.Println(f())
    fmt.Println(f())
    fmt.Println(f())
}
- 功能与java 8 Lambda类似
- 请点击 Run 按钮运行看看
35

接口-interface

// +build OMIT
package main

import "fmt"

type Speaker interface {
    Say(string)
}

type Person struct {
    name string
}

func (p *Person) Say(message string) {
    fmt.Println(p.name+":", message)
}

func SpeakGo(s Speaker) {
    s.Say("Go Train!")
}

func main() {
    p := new(Person)
    p.name = "BingoHuang"
    SpeakGo(p)
}
36

接口-interface

- 类型实现接口时不用提前在定义处声明(implements)

- 只要类型有该接口的方法,就认为实现该接口,这种方式称为: Duck type

- Go没有实现继承(extends),通过匿名组合复用代码,没有庞大的继承树
37

可见性

  type Rect struct {
    X, Y          float64
    width, height float64
  }

  func (r *Rect) Area() float64 {
    return r.width * r.height
  }
- 没有 public, private, internal 等关键字

- 首字母大写对应 public, 小写对应 private,这是针对包外访问,包内全部可见

- 因为没有继承,所以不需要 protected

- internal 名称目录下的代码是私有代码,外部无法访问(除开本 package)
38

其它:

39

再补充 Go 几个知识点

40

Go 内置函数

参见 Go 源码包:builtin/builtin.go
41

Go 操作符

42

小结一下 - Go 优缺点

- 没有 generic
- 包管理一直不完善
- 缺少动态加载库的能力
- 缺少好调试手段(杰哥)
- 开源库还需要更加完善,特别是GUI相关的库
0. 编译性语言         -- c/c++
1. 跨平台             -- java (Go不同平台需要重新编译)
2. 简洁易用           -- python
3. goroutine         -- erlang
4. channel           -- erlang
5. 超强并发           -- scala/node.js
6. 自带GC             -- java/c#
43

Go 生态发展

44

Go 适合的领域

Go 目标是系统级编程语言,任何需要性能+效率的应用,Go 都是不错的选择
45

Go in CNCF - https://l.cncf.io

- Kubernetes
- Prometheus, grpc-go, containerd, CNI, rkt, Jaeger, Notary, Vitess, CoreDNS, NATS
- Rook, Open Policy Agent, Spire
46

Go 在云计算和微服务领域的开源项目

47

Go 学习实践

48

学习 Go 的八大理由 - By astaxie

- 诞生于几位泰山北斗之手
- 出生于 Google 这个名门
- 类 C 语法,GC 内置
- 工程工具
- 接近 C 的运行效率
- 接近 PHP 的开发效率
- 组合的思想
- 无侵入式的接口
49

学习 Go 的八大理由 - By astaxie

- 互联网应用
- 系统编程,网络编程
- 二进制文件
- copy 部署
- 降低心智的并发
- 简易的数据同步
- 强大的编译检查,严格的编码规范
- 完整的软件生命周期工具
50

学习方式

- 学习基本语法和命令操作,参照实例学习
- Effective Go : `https://github.com/bingohuang/effective-go-zh-en` - 我整理的中英版
- Go Tour: `https://tour.golang.org`
- Go By Example: `http://gobyexample.com/`
- Go Team 《The Go Programming》 —— 又称 《Go 语言圣经》,有中译版,非常推荐
- 许式伟  《Go 语言编程》 —— 我的入门书籍
- William 《Go 语言实战》 —— 实战所需
- 谢大    《Go Web 编程》 —— Web 编程入门好书
- 郝林    《Go 并发编程》 —— 第二版必第一版紧凑
- 雨痕    《Go 学习笔记》 —— 精通 Go 好书
51

学习实践

- *Goland*/Intellij IDEA, *VS code*, Vim, Sublime, Atom, LiteIDE, Eclipse
52

最后,引用一个比喻:编程语言是材料,不是工具!

| 类别     | 建筑            |  软件  
| -------- | :------------  | :----  
| 工具     | 起重机等各种机器 | IDE/编译器/调试器/... 
| 材料     | 木材/砖/钢筋/... | c/c++/java/go/...  
| 设计     | 蓝图            | 架构文档 
| 构建     | 建筑工人        | 软件工程师 
| 维护     | 物业           | 技术支持
53

交流讨论

54

交流讨论

55

交流讨论

56

最后

欢迎在这里分享你的 Go 学习总结或疑惑

57

Thank you

Bingo Huang

Use the left and right arrow keys or click the left and right edges of the page to navigate between slides.
(Press 'H' or navigate to hide this message.)