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

Go

维基百科,自由的百科全书

此条目或章节需要时常更新。内容可能会随着时间而有所变化或进展。未有可靠来源臆测内容可能会被移除。若您发现有尚未更新的内容,欢迎您编辑更新
此条目可参照英语维基百科相应条目来扩充。若您熟悉来源语言和主题,请协助参考外语维基百科扩充条目。请勿直接提交机械翻译,也不要翻译不可靠、低品质内容。依版权协议,译文需在编辑摘要注明来源,或于讨论页顶部标记((Translated page))标签。
Go
Go Logo Blue.svg
编程范型编译型可平行化结构化指令式
设计者罗伯特·格瑞史莫英语Robert Griesemer
罗勃·派克
肯·汤普逊
实现者Google
发行时间2009年11月10日,​12年前​(2009-11-10
稳定版本
1.19[1]在维基数据编辑
(2022年8月2日,12天前 )
操作系统LinuxmacOSFreeBSDWindows
许可证BSD
文件扩展名.go
网站https://go.dev/
https://golang.google.cn/[2]
主要实现产品
gc (8g,6g,5g),gccgo
启发语言
COberonLimboNewsqueak[3]
Gopher(囊鼠科),Go的吉祥物
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]

在2016年,Go被软件评价公司TIOBE英语TIOBE Programming Community Index选为“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))。

批评

尽管 Go 的官方与支持者对于语言中不使用泛型异常处理有着大量辩解说词,但批评声也从未停过。在发表 Go 语言 2.0 的草案时,官方称没有泛型异常处理模块对于 Go 发展造成很大的阻碍[10],等同承认 Go 没有这些特色是设计错误。

Go 的垃圾回收机制一直被人诟病,直到 1.8 版本垃圾回收的功能才较为稳定。然而尽管如此,Go 的垃圾回收还是远远落后 JVM 的 G1 和 ZGB。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时,缺少对泛型编程的支持和冗长的异常处理而备受批评。

版本历史

主要版本 发布日期 语言改动[27] 其他改动
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英语Integer 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命令程序[28]

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,其目录结构如下[29]

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[30],并且这些性能都是原生级的,随时都能够关闭、结束,且运行在多个处理器线程上。一个核心里面可以有多个Goroutine,透过GOMAXPROCS参数你能够限制Gorotuine可以占用几个系统线程来避免失控。

在内置的官方包中也不时能够看见Goroutine的应用,像是net/http中用来监听网络服务的函数实际上是创建一个不断执行循环的Goroutine;同时搭配了epoll 等IO多路复用机制维护Goroutine的事件循环

编译器

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

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

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

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

Gccgo目前的开源协议的地址:https://github.com/golang/gofrontend/blob/master/LICENSE页面存档备份,存于互联网档案馆

[33]

参考文献

  1. ^ https://go.dev/doc/devel/release#go1.19。
  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. ^ 存档副本. [2018-09-17]. (原始内容存档于2018-09-17). 
  8. ^ Go Concurrency Patterns. golang.org. [2020-05-07]. (原始内容存档于2021-02-05). 
  9. ^ 存档副本. [2018-09-17]. (原始内容存档于2020-11-08). 
  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. ^ Release History - The Go Programming Language. golang.org. [2018-08-24]. (原始内容存档于2017-02-17). 
  28. ^ 存档副本. [2009-11-20]. (原始内容存档于2013-07-08). 
  29. ^ How to Write Go Code. The Go Programming Language. [2017-11-15]. (原始内容存档于2019-02-13) (英语). 
  30. ^ Max number of goroutines. stackoverflow.com. [2017-03-20]. (原始内容存档于2020-11-25). 
  31. ^ Google公布实现Go 1.5自举的计划. [2015-06-09]. (原始内容存档于2018-08-07). 
  32. ^ Go FAQ: Implementation. [2009-11-12]. (原始内容存档于2013-01-02). 
  33. ^ Gccgo 的官方Readme.md文件

外部链接


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