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).
外部連結
[
??
]
|
---|
| | | 部門
| | |
---|
| ?告
| |
---|
| 通?
| |
---|
| 硬件
| |
---|
| ?件
| |
---|
| 平台
| |
---|
| ??工具
| |
---|
| 出版
| |
---|
| 搜索
| |
---|
| 停止??
| |
---|
| 人物
| |
---|
| 其?
| |
---|
| 相?
| |
---|
| |
|