鍍金池/ 教程/ GO/ 簡(jiǎn)介
版權(quán)
簡(jiǎn)介
Bibliography
接口
通訊
函數(shù)
進(jìn)階
索引
并發(fā)

簡(jiǎn)介

什么是 Go?來(lái)自其網(wǎng)站 [13] 的介紹:

Go 編程語(yǔ)言是一個(gè)使得程序員更加有效率的開(kāi)源項(xiàng)目。Go 是有表達(dá)力、簡(jiǎn)潔、清晰和有效率的。它的并行機(jī)制使其很容易編寫(xiě)多核和網(wǎng)絡(luò)應(yīng)用,而新奇的類型系統(tǒng)允許構(gòu)建有彈性的模塊化程序。Go 編譯到機(jī)器碼非??焖?,同時(shí)具有便利的垃圾回收和強(qiáng)大的運(yùn)行時(shí)反射。它是快速的、靜態(tài)類型編譯語(yǔ)言,但是感覺(jué)上是動(dòng)態(tài)類型的,解釋型語(yǔ)言。

Go 1 是 Go 語(yǔ)言的第一個(gè)穩(wěn)定發(fā)布版本。本文檔的所有練習(xí)都工作于 Go 1 – 如果不能 工作,那就一定是 bug。

本書(shū)使用了下面的約定:

  • 代碼、關(guān)鍵字和注釋使用 Source Code Pro 顯示;
  • 代碼中的額外標(biāo)識(shí)←像這樣顯示;
  • 較長(zhǎng)的標(biāo)識(shí)提供數(shù)字– 1 – 詳細(xì)解釋在其后顯示;
  • (如果需要)行號(hào)在右邊顯示;
  • shell 的例子使用 % 作為輸入符;
  • 用戶在 shell 輸入內(nèi)容的例子用黑體顯示,系統(tǒng)反饋用普通的黑體顯示;
  • 強(qiáng)調(diào)的段落會(huì)縮進(jìn),并在左邊有豎線。

官方文檔

Go 已經(jīng)有大量的文檔。例如 Go Tutorial [12] 和 Effective Go [8]。網(wǎng)站http://golangorg/doc/ 也是絕佳的起點(diǎn)。雖然并不一定要閱讀這些文檔,但是強(qiáng)烈建議這么做。 Go 1 通過(guò)叫做 go doc 的標(biāo)準(zhǔn)程序提供其文檔。如果你想了解內(nèi)建相關(guān)(參閱下一章“運(yùn)算符和內(nèi)建函數(shù)” 小節(jié))的文檔,可以像這樣獲取:

% go doc builtin

在第3 章解釋了如何構(gòu)造你自己的包的文檔。有一些特性讓 Go 與眾不同。

清晰并且簡(jiǎn)潔

Go 努力保持小并且優(yōu)美,你可以在短短幾行代碼里做許多事情;

并行

Go 讓函數(shù)很容易成為非常輕量的線程。這些線程在 Go 中被叫做 goroutines b;

Channel

這些 goroutines 之間的通訊由 channel[18, 25] 完成;

快速

編譯很快,執(zhí)行也很快。目標(biāo)是跟 C 一樣快。編譯時(shí)間用秒計(jì)算;

安全

當(dāng)轉(zhuǎn)換一個(gè)類型到另一個(gè)類型的時(shí)候需要顯式的轉(zhuǎn)換并遵循嚴(yán)格的規(guī)則。Go 有垃圾收集,在 Go 中無(wú)須 free(),語(yǔ)言會(huì)處理這一切;

標(biāo)準(zhǔn)格式化

Go 程序可以被格式化為程序員希望的(幾乎)任何形式,但是官方格式是存在的。標(biāo)準(zhǔn)也非常簡(jiǎn)單:gofmt 的輸出就是官方認(rèn)可的格式;

類型后置

類型在變量名的后面,像這樣 var a int,來(lái)代替 C 中的 int a;

UTF-8

任何地方都是 UTF-8 的,包括字符串以及程序代碼。你可以在代碼中使用 Φ = Φ + 1;

開(kāi)源

Go 的許可證是完全開(kāi)源的,參閱 Go 發(fā)布的源碼中的 LICENSE 文件;

開(kāi)心

用 Go 寫(xiě)程序會(huì)非常開(kāi)心!

Erlang[4] 與 Go 在部分功能上類似。Erlang 和 Go 之間主要的區(qū)別是 Erlang 是函數(shù)式語(yǔ)言,而 Go 是命令式的。Erlang 運(yùn)行在虛擬機(jī)上,而 Go 是編譯的。Go 用起來(lái)感覺(jué)更接近 Unix。

Hello World

在 Go 指南中,用一個(gè)傳統(tǒng)的方式展現(xiàn)了 Go:讓它打印 “Hello World”(Ken Thompson 和 Dennis Ritchie 在 20 世紀(jì) 70 年代,發(fā)布 C 語(yǔ)言的時(shí)候開(kāi)創(chuàng)了這個(gè)先河)。我們不認(rèn)為其他方法可以做得更好,所以就是這個(gè)吧:Go 的 “Hello World”。

http://wiki.jikexueyuan.com/project/learn-go-language/images/1.png" alt="pic" />

逐行閱讀這個(gè)程序。

0 .首行這個(gè)是必須的。所有的 Go 文件以 package 開(kāi)頭,對(duì)于獨(dú)立運(yùn)行的執(zhí)行文件必須 package main;

  1. 這是說(shuō)需要將 fmt 包加入 main。不是 main 的其他包都被稱為庫(kù),其他許多編程語(yǔ)言有著類似的概念(參閱第3 章)。末尾以 // 開(kāi)頭的內(nèi)容是注釋;

  2. 這同樣是注釋,不過(guò)這是被包裹于 // 之間的;

  3. package main 必須首先出現(xiàn),緊跟著是 import。在 Go 中,package 總是首先出現(xiàn),然后是 import,然后是其他所有內(nèi)容。當(dāng) Go 程序在執(zhí)行的時(shí)候,首先調(diào)用的函數(shù)是 main.main(),這是從 C 中繼承而來(lái)。這里定義了這個(gè)函數(shù);

  4. 第 8 行調(diào)用了來(lái)自于 fmt 包的函數(shù)打印字符串到屏幕。字符串由" 包裹,并且可以包 含非 ASCII 的字符。這里使用了希臘文和日文。

編譯和運(yùn)行代碼

構(gòu)建 Go 程序的最佳途徑是使用go 工具。

構(gòu)建 helloworld 只需要:

% go build helloworld.go

結(jié)果是叫做 helloworld 的可執(zhí)行文件。

% ./helloworld
Hello, world; or ? ó?; or こんにちは世界

本書(shū)使用的設(shè)置

  • Go 被安裝在 ?/go,而 $GOROOT 被設(shè)置為 GOROOT=?/go;

  • 希望編譯的 Go 代碼放在 ?/g/src 而 $GOPATH 設(shè)置為 GOPATH=?/g。在使用包的時(shí)候需要用到這個(gè)變量(參閱第 3 章)。

變量、類型和關(guān)鍵字

在接下來(lái)的章節(jié)中,我們將會(huì)了解這個(gè)新語(yǔ)言的變量、基本類型、關(guān)鍵字和控制流。Go 在語(yǔ)法上有著類 C 的感覺(jué)。如果你希望將兩個(gè)(或更多)語(yǔ)句放在一行書(shū)寫(xiě),它們必須用分號(hào) (’;’) 分隔。一般情況下,你不需要分號(hào)。

Go 同其他語(yǔ)言不同的地方在于變量的類型在變量名的后面。不是:int a,而是a int。當(dāng)定義了一個(gè)變量,它默認(rèn)賦值為其類型的 null 值。這意味著,在 var a int 后,a 的值為 0。而 var s string,意味著 s 被賦值為零長(zhǎng)度字符串,也就是 ""。

在 Go 中,聲明和賦值是兩過(guò)程,但是可以連在一起。比較下面作用相同的代碼片段。

http://wiki.jikexueyuan.com/project/learn-go-language/images/2.png" alt="pic" />

在左邊使用了關(guān)鍵字 var 聲明變量,然后賦值給它。右邊的代碼使用了 := 使得在一步內(nèi)完成了聲明和賦值(這一形式只可用在函數(shù)內(nèi))。在這種情況下,變量的類型是由值推演出來(lái)的。值 15 表示是 int 類型,值 false 告訴 Go 它的類型應(yīng)當(dāng)是 bool。多個(gè) var 聲明可以成組;const 和 import 同樣允許這么做。留意圓括號(hào)的使用:

http://wiki.jikexueyuan.com/project/learn-go-language/images/3.png" alt="pic" />

有相同類型的多個(gè)變量同樣可以在一行內(nèi)完成聲明:var x, y int 讓 x 和 y 都是 int 類型變量。同樣可以使用平行賦值:

a, b := 20, 16

讓 a 和 b 都是整數(shù)變量,并且賦值 20 給 a,16 給 b。 一個(gè)特殊的變量名是 _(下劃線)。任何賦給它的值都被丟棄。在這個(gè)例子中,將 35 賦值給 b,同時(shí)丟棄 34。

_, b := 34, 35

Go 的編譯器對(duì)聲明卻未使用的變量在報(bào)錯(cuò)。下面的代碼會(huì)產(chǎn)生這個(gè)錯(cuò)誤:聲明了 i 卻未使用

http://wiki.jikexueyuan.com/project/learn-go-language/images/4.png" alt="pic" />

布爾類型

布爾類型表示由預(yù)定義的常量 true 和 false 代表的布爾判定值。布爾類型是 bool。

數(shù)字類型

Go 有眾所周知的類型如 int,這個(gè)類型根據(jù)你的硬件決定適當(dāng)?shù)拈L(zhǎng)度。意味著在 32 位硬件上,是 32 位的;在 64 位硬件上是 64 位的。注意:int 是 32 或 64 位之一,不會(huì)定義成其他值。uint 情況相同。

如果你希望明確其長(zhǎng)度,你可以使用 int32 或者 uint32。完整的整數(shù)類型列表(符號(hào)和無(wú)符號(hào))是 int8,int16,int32,int64 和 byte,uint8,uint16,uint32,uint64。byte 是 uint8 的別名。浮點(diǎn)類型的值有 float32 和 float64 (沒(méi)有 float 類型)。64 位的整數(shù)和浮點(diǎn)數(shù)總是 64 位的,即便是在 32 位的架構(gòu)上。需要留意的是這些類型全部都是獨(dú)立的,并且混合用這些類型向變量賦值會(huì)引起編譯器錯(cuò)誤,例如下面的代碼:

http://wiki.jikexueyuan.com/project/learn-go-language/images/5.png" alt="pic" />

在行 7 觸發(fā)一個(gè)賦值錯(cuò)誤:

types.go:7: cannot use a + a (type int) as type int32 in assignment

賦值可以用八進(jìn)制、十六進(jìn)制或科學(xué)計(jì)數(shù)法:077,0xFF,1e3 或者 6.022e23 這些都是合法的。

常量

常量在 Go 中,也就是 constant。它們?cè)诰幾g時(shí)被創(chuàng)建,只能是數(shù)字、字符串或布爾值;const x = 42 生成 x 這個(gè)常量??梢允褂?iota c 生成枚舉值。

http://wiki.jikexueyuan.com/project/learn-go-language/images/6.png" alt="pic" />

第一個(gè) iota 表示為 0,因此 a 等于 0,當(dāng) iota 再次在新的一行使用時(shí),它的值增加了 1,因此 b 的值是 1。

也可以像下面這樣,省略 Go 重復(fù)的 = iota:

http://wiki.jikexueyuan.com/project/learn-go-language/images/7.png" alt="pic" />

如果需要,可以明確指定常量的類型:

http://wiki.jikexueyuan.com/project/learn-go-language/images/8.png" alt="pic" />

字符串

另一個(gè)重要的內(nèi)建類型是 string。賦值字符串的例子:

s := "Hello World ! "

字符串在 Go 中是 UTF-8 的由雙引號(hào)(”)包裹的字符序列。如果你使用單引號(hào)(’)則表示一個(gè)字符(UTF-8 編碼)——這種在 Go 中不是 string。

一旦給變量賦值,字符串就不能修改了:在 Go 中字符串是不可變的。從 C 來(lái)的用戶,下面的情況在 Go 中是非法的。

http://wiki.jikexueyuan.com/project/learn-go-language/images/9.png" alt="pic" />

在 Go 中實(shí)現(xiàn)這個(gè),需要下面的方法:

http://wiki.jikexueyuan.com/project/learn-go-language/images/10.png" alt="pic" />

0 .轉(zhuǎn)換 s 為 rune 數(shù)組,查閱在第 4 章“轉(zhuǎn)換” 節(jié)、 59 頁(yè)的內(nèi)容;

  1. 修改數(shù)組的第一個(gè)元素;
  2. 創(chuàng)建新的字符串 s2 保存修改;
  3. 用 fmt.Printf 函數(shù)輸出字符串。

多行字符串

基于分號(hào)的置入(查閱文檔 [8] 的“分號(hào)” 章節(jié)), 你需要小心使用多行字符串。如果這樣寫(xiě):

http://wiki.jikexueyuan.com/project/learn-go-language/images/11.png" alt="pic" />

會(huì)被轉(zhuǎn)換為:

http://wiki.jikexueyuan.com/project/learn-go-language/images/12.png" alt="pic" />

這是錯(cuò)誤的語(yǔ)法,應(yīng)當(dāng)這樣寫(xiě):

http://wiki.jikexueyuan.com/project/learn-go-language/images/13.png" alt="pic" />

Go 就不會(huì)在錯(cuò)誤的地方插入分號(hào)。另一種方式是使用反引號(hào) ` 作為原始字符串符號(hào):

http://wiki.jikexueyuan.com/project/learn-go-language/images/14.png" alt="pic" />

留意最后一個(gè)例子 s 現(xiàn)在也包含換行。不像轉(zhuǎn)義字符串標(biāo)識(shí),原始字符串標(biāo)識(shí)的值在引號(hào)內(nèi)的字符是不轉(zhuǎn)義的。

rune

Rune 是 int32 的別名。用 UTF-8 進(jìn)行編碼。這個(gè)類型在什么時(shí)候使用呢?例如需要遍歷字符串中的字符。可以循環(huán)每個(gè)字節(jié)(僅在使用 US ASCII 編碼字符串時(shí)與字符等價(jià),而它們?cè)?Go 中不存在?。?。因此為了獲得實(shí)際的字符,需要使用 rune 類型。

復(fù)數(shù)

Go 原生支持復(fù)數(shù)。它的變量類型是 complex128 (64 位虛數(shù)部分)。如果需要小一些的,還有 complex64 – 32 位的虛數(shù)部分。復(fù)數(shù)寫(xiě)為 re + imi,re 是實(shí)數(shù)部分,im 是虛數(shù)部分,而 i 是標(biāo)記 ’i’ (p

上一篇:通訊下一篇: