本页使用了标题或全文手工转换

Go

维基百科,自由的百科全书
跳转至: 导航搜索
Go
Golang.png
编程范型 編譯型可平行化結構化指令式
設計者 罗伯特·格瑞史莫Robert Griesemer英语Robert Griesemer
羅勃·派克(Rob Pike)
肯·汤普逊(Ken Thompson)
實作者 Google
发行时间 2009
最新发行时间 1.8.3(2017年5月24日,​5個月前​(2017-05-24[1]
作業系統 LinuxMac OS XFreeBSDWindows
許可證 BSD
網站 http://golang.org/

GoGoogle開發的一种静态强类型編譯型并发型,并具有垃圾回收功能编程语言。為了方便搜索和識別,有时会将其稱為Golang[3]

羅伯特·格瑞史莫英语Robert Griesemer羅勃·派克(Rob Pike)及肯·汤普逊於2007年9月开始设计Go語言,[2],稍後Ian Lance Taylor、Russ Cox加入專案。Go語言是基於Inferno作業系統所開發的。[4]Go語言於2009年11月正式宣布推出,成為開放原始碼專案,并在LinuxMac OS X平台上进行了實現,后来追加了Windows系统下的实现。[5]

目前Go语言每半年发布一个二级版本(即升级1.x到1.y)。

描述[编辑]

Go语言的语法接近C语言,但对于变量的声明英语type declaration有所不同。Go语言支持垃圾回收功能。Go语言的并行模型是以東尼·霍爾交談循序程式(CSP)为基础,采取类似模型的其他语言包括OccamLimbo[2],但它也具有Pi运算的特征,比如通道传输。在1.8版本中開放插件(Plugin)的支持,這意味著現在能從Go語言中動態載入部分函式。

与C++相比,Go語言並不包括如异常处理继承泛型断言虚函数等功能,但增加了 Slice 型、并发、管道、垃圾回收、接口(Interface)等特性的语言级支持[2]。Google 目前仍正在討論是否應該支持泛型,其態度還是很開放的,但在該語言的常見問題列表中,對於断言的存在,則持負面態度,同時也為自己不提供型別繼承來辯護。

不同于Java,Go語言内嵌了关联数组(也称为哈希表(Hashes)或字典(Dictionaries)),就像字符串类型一样。

撰寫風格[编辑]

在Go語言中有幾項規定,而且這些是強制的,當不符合以下規定時編譯將會產生錯誤。

  1. 每行程式結束後不需要撰寫分號(;)。
  2. 大括號({)不能夠換行放置。
  3. IF 判斷式和 For 迴圈不需要以小括號包覆起來。

Go 語言亦有內建 gofmt 工具,能夠自動整理程式碼多餘的空白、變數名稱對齊、並將對齊空白轉換成 Tab。

專案架構[编辑]

Go語言的工作區英语Workspace的資料夾,其結構如下[6]

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並不是線程)。線程屬於系統層面,通常來說建立一個新的線程會消耗較多的資源且管理不易。而 Goroutine就像輕量級的線程,但我們稱其為併發,一個Go程式可以執行超過數萬個 Goroutine[7],並且這些效能都是原生級的,隨時都能夠關閉、結束。一個核心裡面可以有多個Goroutine,透過GOMAXPROCS參數你能夠限制Gorotuine可以佔用幾個系統線程來避免失控。

在內建的官方套件中也不時能夠看見Goroutine的應用,像是net/http中用來監聽網路服務的函式實際上是建立一個不斷執行迴圈的Goroutine。

编译器[编辑]

当前有两个Go語言的编译器的分支。官方编译器gc和gccgo。官方编译器在初期使用C写成,后用go重写从而实现自举[8]。Gccgo是一个使用标准GCC作为后端的Go编译器[9]

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

範例[编辑]

下面是用Go語言写成的Hello World程序。

1 package main
2 
3 import "fmt"
4 
5 func main() {
6 	fmt.Println("Hello, World")
7 }

透過 Go 語言僅需幾行程式碼就完成 HTTP 網頁伺服器的實現:

 1 package main
 2 
 3 import (
 4 	"io"
 5 	"net/http"
 6 )
 7 
 8 func hello(w http.ResponseWriter, r *http.Request) {
 9 	io.WriteString(w, "Hello world!")
10 }
11 
12 func main() {
13 	http.HandleFunc("/", hello)
14 	http.ListenAndServe(":8000", nil)
15 }

下面的例子说明了怎样用 Go 語言去实现一个像 Unix 中的 Echo命令程序[10]

 1 package main
 2 
 3 import (
 4 	"os"
 5 	"flag"
 6 )
 7 
 8 var omitNewline = flag.Bool("n", false, "don't print final newline")
 9 
10 const (
11 	Space   = " "
12 	Newline = "\n"
13 )
14 
15 func main() {
16 	flag.Parse() // Scans the arg list and sets up flags
17 	var s string = ""
18 	for i := 0; i < flag.NArg(); i++ {
19 		if i > 0 {
20 			s += Space
21 		}
22 		s += flag.Arg(i)
23 	}
24 	if !*omitNewline {
25 		s += Newline
26 	}
27 	os.Stdout.WriteString(s)
28 }

同名爭議[编辑]

2003年發表的程式語言 Go!英语Go!_(programming_language),Go 名稱與其雷同。

參考文獻[编辑]

外部連結[编辑]