本页使用了标题或全文手工转换

Go

维基百科,自由的百科全书
(重定向自Go语言
跳到导航 跳到搜索
Go
Go Logo Blue.svg
编程范型編譯型可平行化結構化指令式
設計者罗伯特·格瑞史莫英语Robert Griesemer
羅勃·派克(Rob Pike)
肯·汤普逊(Ken Thompson)
實作者Google
发行时间2009年11月10日,​10年前​(2009-11-10
穩定版本
1.15.2
( 2020年9月9日,​16天前​(2020-09-09[1]
作業系統LinuxmacOSFreeBSDWindows
許可證BSD
網站https://golang.org/
https://golang.google.cn/[2]
主要實作產品
gc (8g,6g,5g),gccgo
啟發語言
COberonLimboNewsqueak[3]

Go(又稱Golang[4])是Google開發的一种静态强类型編譯型并发型,并具有垃圾回收功能编程语言

羅伯特·格瑞史莫英语Robert Griesemer羅勃·派克(Rob Pike)及肯·汤普逊於2007年9月开始设计Go,[3],稍後Ian Lance Taylor、Russ Cox加入專案。Go是基於Inferno作業系統所開發的。[5]Go於2009年11月正式宣布推出,成為開放原始碼專案,支援LinuxmacOSWindows等作業系統。[6] 在2016年,Go被軟體評價公司TIOBE 選為「TIOBE 2016 年最佳語言」。[7]

目前,Go每半年发布一个二级版本(即从a.x升级到a.y)。

描述[编辑]

Go的语法接近C语言,但对于变量的声明英语type declaration有所不同。Go支持垃圾回收功能。Go的并行计算模型是以東尼·霍爾交談循序程式(CSP)为基础,采取类似模型的其他语言包括OccamLimbo[3],Go也具有这个模型的特征,比如通道传输。通过goroutine和通道等并行构造可以建造线程池管道[8]。在1.8版本中開放插件(Plugin)的支持,這意味著現在能從Go中動態載入部分函式。

与C++相比,Go並不包括如枚举异常处理继承泛型断言虚函数等功能,但增加了 切片(Slice) 型、并发、管道、垃圾回收功能接口等特性的语言级支持[3]。Go 2.0版本將支持泛型[9],對於断言的存在,則持負面態度,同時也為自己不提供型別继承來辯護。

不同于Java,Go原生提供了关联数组(也称为哈希表(Hashes)或字典(Dictionaries)),就像字符串类型一样。

历史[编辑]

2007年,Google设计Go,目的在于提高在多核、网络机器(networked machines)、大型代码库(codebases)的情况下的开发效率。[10]当时在Google,设计师们想要解决其他语言使用中的缺点,但是仍保留他们的优点。[11]

设计师们主要受他们之间流传的“不要像C++”启发。[13][14][15]

Go於2009年11月正式宣布推出,[16]版本1.0在2012年3月发布。[17][18]之后,Go广泛应用于Google的产品[19]以及许多其他组织和开源项目。

在2016年11月,Go(一种无衬线体)和Go Mono 字体(一种等宽字体)分别由设计师 Charles Bigelow 和 Kris Holmes 发布。 两种字体均采用了 WGL4 ,并且依照着 DIN 1450 标准,可清晰地使用了 large x-height 和 letterforms 。[20][21]

在2018年8月,原生的图标更换了 。待描述完整 然而,Gopher mascot 仍旧命相同的名字。[22]

在2018年8月,Go的主要贡献者发布了两个关于语言新功能的“草稿设计——泛型异常处理,同时寻求Go用户的反馈。[23][24]Go 由于在1.x时,缺少对 泛型编程 的支持和冗长的 异常处理 而备受批评。

版本历史[编辑]

主要版本 发布日期 语言改动[25] 其他改动
1 – 1.0.3 2012-03-28 初始版本
1.11 – 1.11.6 2018-08-24
  • Go 1.11 增加 WebAssembly 的实验入口。
  • Go 1.11 初次支持新概念 “modules”, 是 GOPATH 的代替品,并支持版本和包的分发。
  • Go 1.11 停止支持 Windows XP 和 Windows Vista.
  • Go 1.11.3 以及之后会修复 crypto/x509 包的 TLS 认证的脆弱性(vulnerability) .
1.12.1 2019-02-25
  • Opt-in 对TLS 1.3支持
  • 增强对 modules 的支持( 为在 Go 1.13 称为默认选择做准备)
  • 支持 windows/arm
  • 提高 macOS & iOS 向前兼容
1.13.1 2019-09-03
  • Go 已支持更统一和更现代化的 数字字义前缀 (number literal prefixes )
  • crypto/tls 包中对TLS 1.3 的支持。(Go 1.14 将会移除 opt-out)
  • 支持错误包装(Error wrapping)


代码示例[编辑]

Hello World[编辑]

下面是用Go写成的Hello World程序:

package main

import "fmt"

func main() {
 fmt.Println("Hello, World")
}

HTTP網頁伺服器[编辑]

透過Go僅需幾行程式碼就完成HTTP網頁伺服器的實現:

package main

import (
 "io"
 "net/http"
)

func hello(w http.ResponseWriter, r *http.Request) {
 io.WriteString(w, "Hello world!")
}

func main() {
 http.HandleFunc("/", hello)
 http.ListenAndServe(":8000", nil)
}

Echo命令程序[编辑]

下面的例子说明了怎样用Go去实现一个像Unix中的Echo命令程序[26]

package main

import (
 "os"
 "flag"
)

var omitNewline = flag.Bool("n", false, "don't print final newline")

const (
 Space   = " "
 Newline = "\n"
)

func main() {
 flag.Parse() // Scans the arg list and sets up flags
 var s string = ""
 for i = 0; i < flag.NArg(); i++ {
  if i > 0 {
   s += Space
  }
  s += flag.Arg(i)
 }
 if !*omitNewline {
  s += Newline
 }
 os.Stdout.WriteString(s)
}

语言特征[编辑]

撰寫風格[编辑]

Go有定義如下的撰寫風格

  1. 每行程式結束後不需要撰寫分號(;)。
  2. 大括號({)不能夠換行放置。
  3. if判斷式和for迴圈不需要以小括號包覆起來。
  4. 使用 tab 做排版

除了第二點外(換行會產生編譯錯誤),在不符合上述規定時,仍舊可以編譯,但使用了內建gofmt工具後,會自動整理程式碼,使之符合規定的撰寫風格。

專案架構[编辑]

Go的工作區英语Workspace位於GOPATH,其目录結構如下[27]

src
pkg
bin

三個目录的用途分別為

目录 用途
src 引用的外部
pkg 編譯時,生成的對象文件英语Object file
bin 編譯後的程式

舉例來說,整個專案目录可能會如下:

bin/
    hello                          # 生成的執行檔
    outyet                         # 生成的執行檔
pkg/
    linux_amd64/
        github.com/golang/example/
            stringutil.a           # 編譯時,生成的對象檔案
src/
    github.com/golang/example/
        .git/                      # 外部 Git 庫的詮釋資料
 hello/
     hello.go               # Git 庫的程式碼
 outyet/
     main.go                # Git 庫的程式碼
     main_test.go           # Git 庫的程式碼(測試用的程式)
 stringutil/
     reverse.go             # Git 庫的程式碼
     reverse_test.go        # Git 庫的程式碼(測試用的程式)
    golang.org/x/image/
        .git/                      # 外部 Git 庫的詮釋資料
 bmp/
     reader.go              # Git 庫的程式碼
     writer.go              # Git 庫的程式碼

轻型线程[编辑]

Go的主要特色在於易于使用的併行設計,叫做Goroutine,透過Goroutine能夠讓程式以異步的方式執行,而不需要擔心一個函式導致程式中斷,因此Go也非常地適合網路服務。假設有個程式,裡面有兩個函式:

func main() {
    // 假設 loop 是一個會重複執行十次的迴圈函式。
    // 迴圈執行完畢才會往下執行。
    loop()
 // 執行另一個迴圈。
 loop()
}

這個時候透過Go讓其中一個函式同步執行,如此就不需要等待該函式執行完後才能執行下一個函式。

func main() {
    // 透過 `go`,我們可以把這個函式同步執行,
    // 如此一來這個函式就不會阻塞主程式的執行。
    go loop()
 // 執行另一個迴圈。
 loop()
}

Goroutine是類似線程的概念,属于纖程(区别于协程线程)。線程屬於系統層面,通常來說建立一個新的線程會消耗較多的資源且管理不易;而协程的主要作用是提供在一個線程內的併發性,卻不能利用多個处理器線程。而 Goroutine就像輕量級的線程,一個Go程式可以執行超過數萬個 Goroutine[28],並且這些效能都是原生級的,隨時都能夠關閉、結束,且運行在多個處理器執行緒上。一個核心裡面可以有多個Goroutine,透過GOMAXPROCS參數你能夠限制Gorotuine可以佔用幾個系統線程來避免失控。

在內建的官方套件中也不時能夠看見Goroutine的應用,像是net/http中用來監聽網路服務的函式實際上是建立一個不斷執行迴圈的Goroutine;同时搭配了epoll 等IO多路復用機制维护Goroutine的事件循环

编译器[编辑]

当前有两个Go编译器分支,分别为官方编译器gc和gccgo。官方编译器在初期使用C写成,后用Go重写从而实现自举英语Bootstrapping (compilers)[29]。Gccgo是一个使用标准GCC作为后端的Go编译器[30]

官方编译器支持跨平台编译(但不支持CGO),允许将原始码编译为可在目标系统、架构上执行的二进制文件。

Gccgo 是Go程序设计语言的编译器前端,最初是在谷歌开发的,并于2009年11月发布。它最初是由Ian Lance Taylor写的,它使用GCC来实现的。 如今,Gccgo 已经不再依赖GCC编译器,因此如果您使用另一个编译器来构建也是可行的。

GCCGO能生成很好的执行代码,但缺少逃逸检测,会在很多小内存的分配和回收上损失一些性能。而另一个Go语言编译器 GC 却实现的不严谨,对32位系统支持很差。 在ARM芯片架构上不使用GCCGO编译的代码是靠不住的。

Gccgo目前的开源协议的地址:https://github.com/golang/gofrontend/blob/master/LICENSE

[31]

參考文獻[编辑]

  1. ^ Release History. [2020-09-09]. (原始内容存档于2017-02-17). 
  2. ^ Golang.google.cn 上线_Google黑板报_新浪博客
  3. ^ 3.0 3.1 3.2 3.3 Language Design FAQ. [2009-11-12]. (原始内容存档于2013-01-02). 
  4. ^ Google-go-language
  5. ^ goyacc.go: Derived from Inferno's utils/iyacc/yacc.c
  6. ^ Installing Go
  7. ^ https://www.bnext.com.tw/article/42761/tiobe-2016-program-language
  8. ^ Go Concurrency Patterns. golang.org. 
  9. ^ https://github.com/golang/go/issues/15292
  10. ^ Go at Google: Language Design in the Service of Software Engineering. [2018-10-08]. 
  11. ^ Pike, Rob. Another Go at Language Design. Stanford EE Computer Systems Colloquium. Stanford University. 2010-04-28 [2020-01-14]. (原始内容存档于2014-06-12).  Video available.
  12. ^ Frequently Asked Questions (FAQ) - The Go Programming Language. golang.org. [2016-02-26]. (原始内容存档于2017-02-25). 
  13. ^ Andrew Binstock. Dr. Dobb's: Interview with Ken Thompson. 2011-05-18 [2014-02-07]. (原始内容存档于2014-03-13). 
  14. ^ Pike, Rob. Less is exponentially more. 2012 [2020-01-14]. (原始内容存档于2016-03-21). 
  15. ^ Robert Griesemer. The Evolution of Go. 2015 [2020-01-14]. (原始内容存档于2017-01-16). 
  16. ^ Griesemer, Robert; Pike, Rob; Thompson, Ken; Taylor, Ian; Cox, Russ; Kim, Jini; Langley, Adam. Hey! Ho! Let's Go!. Google Open Source. Google. [2018-05-17]. 
  17. ^ Shankland, Stephen. Google's Go language turns one, wins a spot at YouTube: The lower-level programming language has matured enough to sport the 1.0 version number. And it's being used for real work at Google.. News. CNet (CBS Interactive Inc). March 30, 2012 [2017-08-06]. Google has released version 1 of its Go programming language, an ambitious attempt to improve upon giants of the lower-level programming world such as C and C++. 
  18. ^ Release History. [2014-12-11]. (原始内容存档于2017-02-17). 
  19. ^ Go FAQ: Is Google using Go internally?. [2013-03-09]. (原始内容存档于2017-02-25). 
  20. ^ Go fonts – The Go Blog. Go. 2016-11-16 [2019-03-12]. (原始内容存档于2019-07-31). 
  21. ^ Go Font TTFs. GitHub. Google. [2019-04-02]. 
  22. ^ Go's New Brand – The Go Blog. blog.golang.org. [2018-11-09]. 
  23. ^ Go 2 Draft Designs. [2018-09-12]. 
  24. ^ The Go Blog: Go 2 Draft Designs. 2018-08-28. 
  25. ^ Release History - The Go Programming Language. golang.org. [2018-08-24]. (原始内容存档于2017-02-17). 
  26. ^ 存档副本. [2009-11-20]. (原始内容存档于2013-07-08). 
  27. ^ How to Write Go Code. The Go Programming Language. [2017-11-15]. (原始内容存档于2019-02-13) (英语). 
  28. ^ Max number of goroutines. stackoverflow.com. [2017-03-20]. 
  29. ^ Google公布实现Go 1.5自举的计划
  30. ^ Go FAQ: Implementation. [2009-11-12]. (原始内容存档于2013-01-02). 
  31. ^ Gccgo 的官方Readme.md文件

外部連結[编辑]