本頁使用了標題或全文手工轉換

Go

維基百科,自由的百科全書
跳至導覽 跳至搜尋
Go
Go Logo Aqua.svg
編程範型 編譯型並行處理結構化指令式
設計者羅伯特·格瑞史莫英語Robert Griesemer
羅勃·派克(Rob Pike)
肯·湯普遜(Ken Thompson)
實作者 Google
面市時間 2009年11月10日,​10年前​(2009-11-10
穩定版本
1.13.6
( 2020年1月9日,​8天前​(2020-01-09[1]
作業系統 LinuxmacOSFreeBSDWindows
許可證 BSD
網站 https://golang.org/
主要實作產品
gc (8g,6g,5g),gccgo
啟發語言
COberonLimboNewsqueak[2]

Go(又稱Golang[3])是Google開發的一種靜態強型別編譯型並發型,並具有垃圾回收功能程式語言

羅伯特·格瑞史莫英語Robert Griesemer羅勃·派克(Rob Pike)及肯·湯普遜於2007年9月開始設計Go,[2],稍後Ian Lance Taylor、Russ Cox加入專案。Go是基於Inferno作業系統所開發的。[4]Go於2009年11月正式宣布推出,成為開放原始碼專案,支援LinuxmacOSWindows等作業系統。[5] 在2016年,Go被軟體評價公司TIOBE 選為「TIOBE 2016 年最佳語言」。[6] ​ 目前,Go每半年發布一個二級版本(即從a.x升級到a.y)。

描述[編輯]

Go的語法接近C語言,但對於變數的聲明英語type declaration有所不同。Go支援垃圾回收功能。Go的平行計算模型是以東尼·霍爾交談循序程式(CSP)為基礎,採取類似模型的其他語言套件括OccamLimbo[2],但它也具有pipeline模型的特徵,比如通道傳輸。在1.8版本中開放外掛程式(Plugin)的支援,這意味著現在能從Go中動態載入部分函式。

與C++相比,Go並不包括如列舉例外處理繼承泛型斷言虛擬函式等功能,但增加了 切片(Slice) 型、並行、管道、垃圾回收功能介面等特性的語言級支援[2]。Go 2.0版本將支援泛型[7],對於斷言的存在,則持負面態度,同時也為自己不提供型別繼承來辯護。

不同於Java,Go原生提供了關聯陣列(也稱為雜湊表(Hashes)或字典(Dictionaries)),就像字串類型一樣。

歷史[編輯]

2007年,Google設計Go,目的在於提高在多核、網路機器(networked machines)、大型代碼庫(codebases)的情況下的開發效率。[8]當時在Google,設計師們想要解決其他語言使用中的缺點,但是仍保留他們的優點。[9]

設計師們主要受他們之間流傳的「不要像C++」啟發。[11][12][13]

Go於2009年11月正式宣布推出,[14]版本1.0在2012年3月發布。[15][16]之後,Go廣泛應用於Google的產品[17]以及許多其他組織和開源專案。

在2016年11月,Go(一種無襯線體)和Go Mono 字型(一種等寬字型)分別由設計師 Charles Bigelow 和 Kris Holmes 發布。 兩種字型均採用了 WGL4 ,並且依照著 DIN 1450 標準,可清晰地使用了 large x-height 和 letterforms 。[18][19]

在2018年8月,原生的圖示更換了 。待描述完整 然而,Gopher mascot 仍舊命相同的名字。[20]

在2018年8月,Go的主要貢獻者發布了兩個關於語言新功能的「草稿設計——泛型例外處理,同時尋求Go用戶的回饋。[21][22]Go 由於在1.x時,缺少對 泛型編程 的支援和冗長的 例外處理 而備受批評。

撰寫風格[編輯]

Go有定義如下的撰寫風格

  1. 每行程式結束後不需要撰寫分號(;)。
  2. 大括號({)不能夠換行放置。
  3. if判斷式和for迴圈不需要以小括號包覆起來。
  4. 使用 tab 做排版

除了第二點外(換行會產生編譯錯誤),在不符合上述規定時,仍舊可以編譯,但使用了內建gofmt工具後,會自動整理程式碼,使之符合規定的撰寫風格。

專案架構[編輯]

Go的工作區英語Workspace位於GOPATH,其目錄結構如下[23]

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

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

編譯器[編輯]

目前有兩個Go編譯器分支,分別為官方編譯器gc和gccgo。官方編譯器在初期使用C寫成,後用Go重寫從而實現自舉英語Bootstrapping (compilers)[25]。Gccgo是一個使用標準GCC作為後端的Go編譯器[26]

官方編譯器支援跨平台編譯(但不支援CGO),允許將原始碼編譯為可在目標系統、架構上執行的二進位檔案。

範例[編輯]

下面是用Go寫成的Hello World程式。

package main

import "fmt"

func main() {
	fmt.Println("Hello, World")
}

透過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)
}

下面的例子說明了怎樣用Go去實現一個像Unix中的Echo命令程式[27]

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


參考文獻[編輯]

  1. ^ Release History. [2020-01-09]. 
  2. ^ 2.0 2.1 2.2 2.3 Language Design FAQ
  3. ^ Google-go-language
  4. ^ goyacc.go: Derived from Inferno's utils/iyacc/yacc.c
  5. ^ Installing Go
  6. ^ https://www.bnext.com.tw/article/42761/tiobe-2016-program-language
  7. ^ https://github.com/golang/go/issues/15292
  8. ^ Go at Google: Language Design in the Service of Software Engineering. [October 8, 2018]. 
  9. ^ Pike, Rob. Another Go at Language Design. Stanford EE Computer Systems Colloquium. Stanford University. April 28, 2010.  Video available.
  10. ^ Frequently Asked Questions (FAQ) - The Go Programming Language. golang.org. [February 26, 2016]. 
  11. ^ Andrew Binstock. Dr. Dobb's: Interview with Ken Thompson. May 18, 2011 [February 7, 2014]. 
  12. ^ Pike, Rob. Less is exponentially more. 2012. 
  13. ^ Robert Griesemer. The Evolution of Go. 2015. 
  14. ^ Griesemer, Robert; Pike, Rob; Thompson, Ken; Taylor, Ian; Cox, Russ; Kim, Jini; Langley, Adam. Hey! Ho! Let's Go!. Google Open Source. Google. [May 17, 2018]. 
  15. ^ 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 [August 6, 2017]. 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++. 
  16. ^ Release History. 
  17. ^ Go FAQ: Is Google using Go internally?. [March 9, 2013]. 
  18. ^ Go fonts – The Go Blog. Go. 16 November 2016 [12 March 2019]. 
  19. ^ Go Font TTFs. GitHub. Google. [April 2, 2019]. 
  20. ^ Go's New Brand – The Go Blog. blog.golang.org. [2018-11-09]. 
  21. ^ Go 2 Draft Designs. [September 12, 2018]. 
  22. ^ The Go Blog: Go 2 Draft Designs. August 28, 2018. 
  23. ^ How to Write Go Code. The Go Programming Language (英語). 
  24. ^ Max number of goroutines. stackoverflow.com. [2017-03-20]. 
  25. ^ Google公布實現Go 1.5自舉的計劃
  26. ^ Go FAQ: Implementation
  27. ^ http://golang.org/doc/go_tutorial.html

外部連結[編輯]