Gopher(囊鼠科 ),Go的吉祥物
Go (又稱Golang [ 4] )是Google 開發的一种静态 强类型 、編譯型 、并发型 ,并具有垃圾回收 功能的编程语言 。
羅伯特·格瑞史莫 、羅勃·派克 及肯·汤普逊 於2007年9月开始设计Go,[ 3] 稍後伊恩·蘭斯·泰勒(Ian Lance Taylor )、拉斯·考克斯(Russ Cox )加入專案。Go是基於Inferno 作業系統 所開發的。[ 5] Go於2009年11月正式宣布推出,成為開放原始碼 專案,支援Linux 、macOS 、Windows 等作業系統。[ 6]
在2009年与2016年,Go被軟體評價公司TIOBE 選為「TIOBE 2016年最佳語言」。[ 7] [ 8]
目前,Go每半年发布一个二级版本(即从a.x 升级到a.y )。
描述
Go的语法接近C语言 ,但对于变量的声明 有所不同。Go支持垃圾回收 功能。Go的并行计算 模型是以東尼·霍爾 的通信顺序进程 (CSP)为基础,采取类似模型的其他语言包括Occam 和Limbo [ 3] ,Go也具有这个模型的特征,比如通道 传输。通过goroutine和通道等并行构造可以建造线程池 和管道 等[ 9] 。在Go 1.8版本中開放插件(Plugin)的支持,這意味著現在能從Go中動態載入部分函式。
与C++相比,Go並不包括如枚举 、异常处理 、继承 、泛型 (此功能在Go 1.18版本中加入)、断言 、虚函数 等功能,但增加了切片(Slice)类型、并发、管道、垃圾回收 、接口 等特性的语言级支持[ 3] 。對於断言 的存在,則持負面態度,同時也為自己不提供型別继承 來辯護。
不同于Java ,Go原生提供了关联数组 (也称为哈希表 (Hashes)或字典(Dictionaries))。
批評
儘管 Go 的官方與支持者對於語言中不使用泛型 與異常處理 有著大量辯解說詞,但批評聲也從未停過。在發表 Go 語言 2.0 的草案時,官方稱沒有泛型 、異常處理 與模組 對於 Go 發展造成很大的阻礙[ 10] ,等同承認 Go 沒有這些特色是設計錯誤。
Go 的垃圾回收 機制一直被人詬病,直到 1.8 版本垃圾回收 的功能才較為穩定。然而儘管如此,Go 的垃圾回收還是遠遠落後 JVM 的 G1 和 ZGC。Discord 的研發團隊在2020年初甚至發表一篇部落格,宣布把其中一個服務由從 Go 轉移至 Rust ,理由是 Go 的垃圾回收會導致每2分鐘出現一次卡頓,並且 Discord 研發團隊測試了 Go 語言的1.8、1.9、1.10版本這個問題都沒有改善[ 11] 。
历史
2007年,Google 设计Go,目的在于提高在多核 、网络机器(networked machines)、大型代码库 (codebases)的情况下的开发效率。[ 12] 当时在Google,设计师们想要解决其他语言使用中的缺点,但是仍保留他们的优点。[ 13]
设计师们主要受他们之间流传的“不要像C++”启发。[ 15] [ 16] [ 17]
Go於2009年11月正式宣布推出,[ 18] 版本1.0在2012年3月发布。[ 19] [ 20] 之后,Go广泛应用于Google的产品[ 21] 以及许多其他组织和开源项目。
在2016年11月,Go(一种无衬线体 )和Go Mono 字体(一种等宽字体 )分别由设计师查爾斯·比格洛 和克莉絲·荷姆斯 发布。两种字体均采用了WGL4 ,并且依照着 DIN 1450 标准,可清晰地使用了 large x-height 和 letterforms 。[ 22] [ 23]
在2018年8月,原生的图标更换了。待描述完整 然而,Gopher mascot 仍旧命相同的名字。[ 24]
在2018年8月,Go的主要贡献者发布了两个关于语言新功能的“草稿设计——泛型 和异常处理 ,同时寻求Go用户的反馈。[ 25] [ 26] Go 由于在1.x时,缺少对泛型 编程的支持和冗长的异常处理 而备受批评。
版本历史
Go 1 保證語言規範[ 27] 和標準庫的主要部分相容。直到目前的 Go 1.20 發布[ 28] ,所有版本都履行了這個承諾。
每個主要的 Go 發布版本會受到支援,直到出現兩個新的主要版本為止。[ 29]
Release
Status
Release date
Maintenance end
舊版本,不再支援: go1
舊版本,不再支援: End-of-Life
2012-03-28
2013-12-01
舊版本,不再支援: go1.1
舊版本,不再支援: End-of-Life
2013-05-13
2014-06-18
舊版本,不再支援: go1.2
舊版本,不再支援: End-of-Life
2013-12-01
2014-12-10
舊版本,不再支援: go1.3
舊版本,不再支援: End-of-Life
2014-06-18
2015-08-19
舊版本,不再支援: go1.4
舊版本,不再支援: End-of-Life
2014-12-10
2016-02-17
舊版本,不再支援: go1.5
舊版本,不再支援: End-of-Life
2015-08-19
2016-08-15
舊版本,不再支援: go1.6
舊版本,不再支援: End-of-Life
2016-02-17
2017-02-16
舊版本,不再支援: go1.7
舊版本,不再支援: End-of-Life
2016-08-15
2017-08-24
舊版本,不再支援: go1.8
舊版本,不再支援: End-of-Life
2017-02-16
2018-02-16
舊版本,不再支援: go1.9
舊版本,不再支援: End-of-Life
2017-08-24
2018-08-24
舊版本,不再支援: go1.10
舊版本,不再支援: End-of-Life
2018-02-16
2019-02-25
舊版本,不再支援: go1.11
舊版本,不再支援: End-of-Life
2018-08-24
2019-09-03
舊版本,不再支援: go1.12
舊版本,不再支援: End-of-Life
2019-02-25
2020-02-25
舊版本,不再支援: go1.13
舊版本,不再支援: End-of-Life
2019-09-03
2020-08-11
舊版本,不再支援: go1.14
舊版本,不再支援: End-of-Life
2020-02-25
2021-02-16
舊版本,不再支援: go1.15
舊版本,不再支援: End-of-Life
2020-08-11
2021-08-16
舊版本,不再支援: go1.16
舊版本,不再支援: End-of-Life
2021-02-16
2022-03-15
舊版本,不再支援: go1.17
舊版本,不再支援: End-of-Life
2021-08-16
2022-08-02
舊版本,不再支援: go1.18
舊版本,不再支援: End-of-Life
2022-03-15
2023-02-01
舊版本,不再支援: go1.19
舊版本,不再支援: End-of-Life
2022-08-02
2023-08-08
舊版本,不再支援: go1.20
舊版本,不再支援: End-of-Life
2023-02-01
Q1 2024
當前版本: go1.21
當前版本: Maintenance
2023-08-08
Q3 2024
當前版本: go1.22
當前版本: Current
2024-02-06
Q1 2025
格式:
舊版本
舊版本,仍被支援
当前版本
最新的预览版
未来版本
代码示例
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命令 程序[ 30] :
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有定義如下的撰寫風格:
每行程式結束後不需要撰寫分號;
。
大括號{
不能夠換行放置。
if
判斷式和for
迴圈不需要以小括號包覆起來。
使用 tab 做排版
除了第二點外(換行會產生編譯錯誤),在不符合上述規定時,仍舊可以編譯,但使用了內建gofmt工具後,會自動整理程式碼,使之符合規定的撰寫風格。
專案架構
module
Go 採用 module 的概念(於 go1.11才開始啟用[ 31] ,舊版本請參閱工作區 ),每個專案都是一個 module ,而每個 module 底下會有個 go.mod
的檔案,來管理該 module 所引用的外部庫、開發版本……等等。
一個 module 的資料夾目錄可能如下
go.mod
hello/
hello.go
outyet/
main.go
main_test.go # 測試用的程式
stringutil/
reverse.go
reverse_test.go # 測試用的程式
bmp/
reader.go
writer.go
然後 go.mod 的內容可能為
module example.org/go-mod-sample
go 1.11
require (
github.com/golang/example v0.0.0-20220412213650-2e68773dfca0
golang.org/x/image v0.1.0
)
工作區
Go的工作區 位於GOPATH
,其目录結構如下[ 32] :
src
pkg
bin
三個目录的用途分別為
目录
用途
src
引用的外部庫
pkg
編譯 時,生成的對象文件
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[ 33] ,並且這些效能都是原生級的,隨時都能夠關閉、結束,且運行在多個處理器執行緒上。一個核心裡面可以有多個Goroutine,透過GOMAXPROCS參數你能夠限制Gorotuine可以佔用幾個系統線程來避免失控。
在內建的官方套件中也不時能夠看見Goroutine的應用,像是net/http中用來監聽網路服務的函式實際上是建立一個不斷執行迴圈的Goroutine;同时搭配了epoll 等IO多路复用 機制维护Goroutine的事件循环 。
编译器
当前有两个Go编译器 分支,分别为官方编译器gc和gccgo。官方编译器在初期使用C写成,后用Go重写从而实现自举 [ 34] 。Gccgo是一个使用标准GCC作为后端的Go编译器[ 35] 。
官方编译器支持跨平台编译(但不支持CGO),允许将原始码编译为可在目标系统、架构上执行的二进制文件。
应用
由于go的原生跨平台,以及大量的官方库,被用于大量开源程序,例如:docker 、Syncthing 、ipfs 、Hugo 、caddy 、以太坊 、V2Ray 、Gitea 、TiDB 。
參考文獻
^ Release History .
^ Golang.google.cn 上线_Google黑板报_新浪博客 . [2020-09-14 ] . (原始内容 存档于2021-08-14).
^ 3.0 3.1 3.2 3.3 Language Design FAQ . [2009-11-12 ] . (原始内容存档 于2013-01-02).
^ Google-go-language . [2018-05-07 ] . (原始内容存档 于2020-11-28).
^ goyacc.go: Derived from Inferno's utils/iyacc/yacc.c . [2009-11-20 ] . (原始内容存档 于2010-08-02).
^ Installing Go . [2009-11-12 ] . (原始内容存档 于2012-03-20).
^ Go 首次冲进前八!曾两次夺得年度编程语言,也曾跌至百名开外 | TIOBE 2 月榜单发布_排名_Top_变化 . www.sohu.com.
^ 存档副本 . [2018-09-17 ] . (原始内容存档 于2018-09-17).
^ Go Concurrency Patterns . golang.org. [2020-05-07 ] . (原始内容存档 于2021-02-05).
^ Go 2 Draft Designs . [2021-03-15 ] . (原始内容 存档于2021-01-26).
^ Why Discord is switching from Go to Rust . [2021-03-15 ] . (原始内容 存档于2022-05-11).
^ Go at Google: Language Design in the Service of Software Engineering . [2018-10-08 ] . (原始内容存档 于2021-01-25).
^ 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 (页面存档备份 ,存于互联网档案馆 ).
^ Frequently Asked Questions (FAQ) - The Go Programming Language . golang.org. [2016-02-26 ] . (原始内容存档 于2017-02-25).
^ Andrew Binstock. Dr. Dobb's: Interview with Ken Thompson . 2011-05-18 [2014-02-07 ] . (原始内容存档 于2014-03-13).
^ Pike, Rob. Less is exponentially more . 2012 [2020-01-14 ] . (原始内容存档 于2016-03-21).
^ Robert Griesemer. The Evolution of Go . 2015 [2020-01-14 ] . (原始内容存档 于2017-01-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 ] . (原始内容存档 于2021-01-26).
^ 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 ] . (原始内容存档 于2020-11-25). 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++.
^ Release History . [2014-12-11 ] . (原始内容存档 于2017-02-17).
^ Go FAQ: Is Google using Go internally? . [2013-03-09 ] . (原始内容存档 于2017-02-25).
^ Go fonts – The Go Blog . Go. 2016-11-16 [2019-03-12 ] . (原始内容存档 于2019-07-31).
^ Go Font TTFs . GitHub. Google. [2019-04-02 ] . (原始内容存档 于2019-07-31).
^ Go's New Brand – The Go Blog . blog.golang.org. [2018-11-09 ] . (原始内容存档 于2020-11-25).
^ Go 2 Draft Designs . [2018-09-12 ] . (原始内容存档 于2021-01-26).
^ The Go Blog: Go 2 Draft Designs . 2018-08-28 [2020-01-14 ] . (原始内容存档 于2021-01-31).
^ Go 1 and the Future of Go Programs . golang.org. [2023-04-12 ] . (原始内容存档 于2017-10-02).
^ Go 1.20 Release Notes . go.dev. [2023-04-12 ] . (原始内容存档 于2023-05-30).
^ Release History . golang.org. [2023-04-12 ] . (原始内容存档 于2017-02-17).
^ 存档副本 . [2009-11-20 ] . (原始内容存档 于2013-07-08).
^ Go 1.11 Release Notes . The Go Programming Language. [2022-11-18 ] . (原始内容存档 于2023-01-03).
^ How to Write Go Code . The Go Programming Language. [2017-11-15 ] . (原始内容存档 于2019-02-13) (英语) .
^ Max number of goroutines . stackoverflow.com. [2017-03-20 ] . (原始内容存档 于2020-11-25).
^ Google公布实现Go 1.5自举的计划 . [2015-06-09 ] . (原始内容存档 于2018-08-07).
^ Go FAQ: Implementation . [2009-11-12 ] . (原始内容存档 于2013-01-02).
外部連結
部門 广告 通讯 硬件 软件 平台 开发工具 出版 搜索
停止开发 人物
其它
相关