Go

本页使用了标题或全文手工转换
?基百科,自由的百科全?
Go
?程范型 編譯型 可平行化 結構化 指令式
設計者 羅伯特·格瑞史莫 英? Robert Griesemer
羅勃·派克
肯·?普?
實作者 Google
?行?? 2009年11月10日 ,​14年前 ​( 2009-11-10
?前版本
  • 1.22.3 (2024年5月7日) [1]
編輯維基數據鏈接
操作系? Linux macOS FreeBSD Windows
許可證 BSD
文件?展名 .go
網站 https://go.dev/
https://golang.google.cn/ [2]
主要實作?品
gc (8g,6g,5g),gccgo
?發語言
C Oberon Limbo Newsqueak [3]
Gopher( 囊鼠科 ),Go的吉祥物

Go (又稱 Golang [4] )是 Google 開發的一? ?? 强?型 編譯型 ??型 ,?具有 ??回收 功能的 ?程?言

羅伯特·格瑞史莫 英? Robert Griesemer 羅勃·派克 肯·?普? 於2007年9月?始??Go, [3] 稍後伊恩·蘭斯·泰勒( Ian Lance Taylor )、拉斯·考克斯( Russ Cox )加入專案。Go是基於 Inferno 作業系統 所開發的。 [5] Go於2009年11月正式宣布推出,成? 開放原始碼 專案,支援 Linux macOS Windows 等作業系統。 [6]

在2009年?2016年,Go被軟體評價公司 TIOBE 英? TIOBE Programming Community Index 選?「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 字?(一? 等?字? )分?由??? ?爾斯·比格洛 英? Charles Bigelow 克莉絲·荷姆斯 英? Kris Holmes ?布。??字?均采用了 WGL4 英? 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有定義如下的撰寫風格:

  1. 每行程式結束後不需要撰寫分號 ;
  2. 大括號 { 不能?換行放置。
  3. if 判斷式和 for ?圈不需要以小括號包覆起來。
  4. 使用 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的 工作區 英? Workspace 位於 GOPATH ,其目?結構如下 [32]

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 [33] ,?且這些效能都是原生級的,隨時都能?關閉、結束,且運行在多個處理器執行?上。一個核心裡面可以有多個Goroutine,透過GOMAXPROCS參數?能?限制Gorotuine可以?用幾個系統線程來避免失控。

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

??器 [ ?? ]

?前有??Go ??器 分支,分??官方??器gc和gccgo。官方??器在初期使用C?成,后用Go重??而?? 自? 英? Bootstrapping (compilers) [34] 。Gccgo是一?使用?准GCC作?后端的Go??器 [35]

官方??器支持跨平台??(但不支持CGO),允??原始????可在目?系?、架?上?行的二?制文件。

?用 [ ?? ]

由于go的原生跨平台,以及大量的官方?,被用于大量?源程序,例如: docker Syncthing ipfs Hugo caddy 以太坊 V2Ray Gitea TiDB

參考文獻 [ ?? ]

  1. ^ Release History .  
  2. ^ Golang.google.cn 上?_Google黑板?_新浪博客 . [ 2020-09-14 ] . ( 原始?容 存?于2021-08-14).  
  3. ^ 3.0 3.1 3.2 3.3 Language Design FAQ . [ 2009-11-12 ] . (原始?容 存? 于2013-01-02).  
  4. ^ Google-go-language . [ 2018-05-07 ] . (原始?容 存? 于2020-11-28).  
  5. ^ goyacc.go: Derived from Inferno's utils/iyacc/yacc.c . [ 2009-11-20 ] . (原始?容 存? 于2010-08-02).  
  6. ^ Installing Go . [ 2009-11-12 ] . (原始?容 存? 于2012-03-20).  
  7. ^ Go 首次??前八!曾?次?得年度?程?言,也曾跌至百名?外 | TIOBE 2 月榜??布_排名_Top_?化 . www.sohu.com.  
  8. ^ 存?副本 . [ 2018-09-17 ] . (原始?容 存? 于2018-09-17).  
  9. ^ Go Concurrency Patterns . golang.org. [ 2020-05-07 ] . (原始?容 存? 于2021-02-05).  
  10. ^ Go 2 Draft Designs . [ 2021-03-15 ] . ( 原始?容 存?于2021-01-26).  
  11. ^ Why Discord is switching from Go to Rust . [ 2021-03-15 ] . ( 原始?容 存?于2022-05-11).  
  12. ^ Go at Google: Language Design in the Service of Software Engineering . [ 2018-10-08 ] . (原始?容 存? 于2021-01-25).  
  13. ^ 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 ?面存??? ,存于 互???案? ).
  14. ^ Frequently Asked Questions (FAQ) - The Go Programming Language . golang.org. [ 2016-02-26 ] . (原始?容 存? 于2017-02-25).  
  15. ^ Andrew Binstock. Dr. Dobb's: Interview with Ken Thompson . 2011-05-18 [ 2014-02-07 ] . (原始?容 存? 于2014-03-13).  
  16. ^ Pike, Rob. Less is exponentially more . 2012 [ 2020-01-14 ] . (原始?容 存? 于2016-03-21).  
  17. ^ Robert Griesemer. The Evolution of Go . 2015 [ 2020-01-14 ] . (原始?容 存? 于2017-01-16).  
  18. ^ 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).  
  19. ^ 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++.  
  20. ^ Release History . [ 2014-12-11 ] . (原始?容 存? 于2017-02-17).  
  21. ^ Go FAQ: Is Google using Go internally? . [ 2013-03-09 ] . (原始?容 存? 于2017-02-25).  
  22. ^ Go fonts ? The Go Blog . Go. 2016-11-16 [ 2019-03-12 ] . (原始?容 存? 于2019-07-31).  
  23. ^ Go Font TTFs . GitHub. Google. [ 2019-04-02 ] . (原始?容 存? 于2019-07-31).  
  24. ^ Go's New Brand ? The Go Blog . blog.golang.org. [ 2018-11-09 ] . (原始?容 存? 于2020-11-25).  
  25. ^ Go 2 Draft Designs . [ 2018-09-12 ] . (原始?容 存? 于2021-01-26).  
  26. ^ The Go Blog: Go 2 Draft Designs . 2018-08-28 [ 2020-01-14 ] . (原始?容 存? 于2021-01-31).  
  27. ^ Go 1 and the Future of Go Programs . golang.org. [ 2023-04-12 ] . (原始?容 存? 于2017-10-02).  
  28. ^ Go 1.20 Release Notes . go.dev. [ 2023-04-12 ] . (原始?容 存? 于2023-05-30).  
  29. ^ Release History . golang.org. [ 2023-04-12 ] . (原始?容 存? 于2017-02-17).  
  30. ^ 存?副本 . [ 2009-11-20 ] . (原始?容 存? 于2013-07-08).  
  31. ^ Go 1.11 Release Notes . The Go Programming Language. [ 2022-11-18 ] . (原始?容 存? 于2023-01-03).  
  32. ^ How to Write Go Code . The Go Programming Language. [ 2017-11-15 ] . (原始?容 存? 于2019-02-13) (英?) .  
  33. ^ Max number of goroutines . stackoverflow.com. [ 2017-03-20 ] . (原始?容 存? 于2020-11-25).  
  34. ^ Google公布??Go 1.5自?的?? . [ 2015-06-09 ] . (原始?容 存? 于2018-08-07).  
  35. ^ Go FAQ: Implementation . [ 2009-11-12 ] . (原始?容 存? 于2013-01-02).  

外部連結 [ ?? ]