For faster navigation, this Iframe is preloading the Wikiwand page for Go.

Go

此条目可参照英语维基百科相应条目来扩充。若您熟悉来源语言和主题,请协助参考外语维基百科扩充条目。请勿直接提交机械翻译,也不要翻译不可靠、低品质内容。依版权协议,译文需在编辑摘要注明来源,或于讨论页顶部标记((Translated page))标签。
Go
编程范型编译型可平行化结构化指令式
设计者罗伯特·格瑞史莫英语Robert Griesemer
罗勃·派克
肯·汤普逊
实现者Google
发行时间2009年11月10日,​14年前​(2009-11-10
当前版本
  • 1.22.4 (2024年6月4日)[1]
编辑维基数据链接
操作系统LinuxmacOSFreeBSDWindows
许可证BSD
文件扩展名.go
网站https://go.dev/
https://golang.google.cn/[2]
主要实现产品
gc (8g,6g,5g),gccgo
启发语言
COberonLimboNewsqueak[3]
Gopher(囊鼠科),Go的吉祥物

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

罗伯特·格瑞史莫英语Robert Griesemer罗勃·派克肯·汤普逊于2007年9月开始设计Go,[3]稍后伊恩·兰斯·泰勒(Ian Lance Taylor)、拉斯·考克斯(Russ Cox)加入项目。Go是基于Inferno操作系统所开发的。[5]Go于2009年11月正式宣布推出,成为开放原始码项目,支持LinuxmacOSWindows等操作系统。[6]

在2009年与2016年,Go被软件评价公司TIOBE英语TIOBE Programming Community Index选为“TIOBE 2016年最佳语言”。[7][8]

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

描述

Go的语法接近C语言,但对于变量的声明有所不同。Go支持垃圾回收功能。Go的并行计算模型是以东尼·霍尔通信顺序进程(CSP)为基础,采取类似模型的其他语言包括OccamLimbo[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的原生跨平台,以及大量的官方库,被用于大量开源程序,例如:dockerSyncthingipfsHugocaddy以太坊V2RayGiteaTiDB

参考文献

  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). 

外部链接


{{bottomLinkPreText}} {{bottomLinkText}}
Go
Listen to this article

This browser is not supported by Wikiwand :(
Wikiwand requires a browser with modern capabilities in order to provide you with the best reading experience.
Please download and use one of the following browsers:

This article was just edited, click to reload
This article has been deleted on Wikipedia (Why?)

Back to homepage

Please click Add in the dialog above
Please click Allow in the top-left corner,
then click Install Now in the dialog
Please click Open in the download dialog,
then click Install
Please click the "Downloads" icon in the Safari toolbar, open the first download in the list,
then click Install
{{::$root.activation.text}}

Install Wikiwand

Install on Chrome Install on Firefox
Don't forget to rate us

Tell your friends about Wikiwand!

Gmail Facebook Twitter Link

Enjoying Wikiwand?

Tell your friends and spread the love:
Share on Gmail Share on Facebook Share on Twitter Share on Buffer

Our magic isn't perfect

You can help our automatic cover photo selection by reporting an unsuitable photo.

This photo is visually disturbing This photo is not a good choice

Thank you for helping!


Your input will affect cover photo selection, along with input from other users.

X

Get ready for Wikiwand 2.0 🎉! the new version arrives on September 1st! Don't want to wait?