這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1.GO語言開發環境搭建
1.1編譯環境安裝
點選連結http://code.google.com/p/go/downloads/list
選擇一個版本,本人下載的是go1.0.3.windows-386.msi
雙擊安裝,選擇安裝一個安裝主目錄:例如,C:\Go,不需要配置什麼東西。
1.2整合式開發環境IDE安裝配置
開啟連結:http://code.google.com/p/golangide/downloads/list
下載一個版本:如liteidex17.windows.7z
下載完畢後在某個目錄下解壓即可
點擊liteide.exe,開啟開發介面。
配置環境變數
菜單:查看→選項,選擇LiteEnv,配置環境變數,有三個檔案,system.env,win32.env,win32-user-env需要配置,配置很簡單,只需要修改上一步安裝的編譯環境目錄即可,三個檔案都一樣。
GOROOT=C:\Go
GOBIN=C:\Go\bin
取消掉PAHT前的#號,其他的不用修改
選擇查看→設定GOPATH,重新整理就可以看到system 的GOPATH,瀏覽自訂的GOPATH,設定存放代碼的空間目錄,開發環境就搭建好了
2.HelloWorld!
語言"出生"後"說"的的第一句話都是,Hello World!
使用GO語言,是這樣說的:
1 package main2 3 import (4 "fmt"5 )6 7 func main() {8 fmt.Println("Hello World!")9 }
編譯後運行即可出現:Hello World!
3.初見GO語言
GO語言Google開發的新語言。有如下特性
自動記憶體回收、更豐富的內建資料類型、函數多傳回值、錯誤處理、匿名函數和閉包、類型和介面、並發編程、反射、多語言混合編程
1 package main 2 3 // 我們需要使用fmt包中的Println()函數 4 import "fmt"5 6 func main() { 7 fmt.Println("Hello, world!") 8 }
3.1代碼解析
package main
每個GO原始碼檔案的開頭聲明該Go代碼所屬的包,包是Go語言裡最基本的分發單位,要產生可執行程式,必須建立一個名字為main的包,並且在該包中包含一個叫main()的函數(該函數是Go可執行程式的執行起點)。
func main()
主函數main(),該函數是執行程式的起點,不能帶參數,也不能定義傳回值。命令傳入的參數在os.Args變數中儲存。如果需要支援命令列開關,使用flag包。
import 導包
匯入該程式所需要的其他包。由於用到了系統函數Println(),所以匯入該函數所屬的fmt包。
注意
不能把原始碼檔案中沒有用到的包導進去,否則Go編譯器會報編譯錯誤
func關鍵字
所有的Go函數(包括在對象編程中會提到的類型成員函數)以關鍵字func開頭。一個常規的函數定義如下:
1 func 函數名(參數列表)(傳回值列表){2 //函數體3 }
可以看出Go語言與其他語言定義函數的區別,它把傳回值列表也列在裡面。
對應樣本:
1 func Compute(value1 int,value2 float64)(result float64,err error){2 //函數體3 }
Go支援多個傳回值。上面的函數Compute()返回了兩個值,一個叫result,一個是err,並不是所有傳回值都必須賦值,如果沒有明確賦值的傳回值被設定為預設值,會根據基礎資料型別 (Elementary Data Type)對傳回值初始化,float64為0.0, error為nil,也就是result是0.0 err為nil
注釋:
Go程式的代碼注釋有兩種:塊注釋和行注釋
/*
塊注釋
*/
//行注釋
語句結束符號
關於語句結束符號:Go程式不要求開發人員在每個語句後面加上分號表示語句結束,當然加上也可以,但Google提供的IDE開發工具在加上分號;後編譯時間會自動消掉分號
大括弧位置
在Java程式設計裡面有提到過大括弧怎麼放。Go語言中,在函數的傳回值後面緊著函數體的左大括弧,不能另起一行,這一點與Java通常用法是一致的,也有人把同一個層級的函數體左括弧單獨起一行,與右括弧放在一列,這樣在Go語言中是不行的。
1 func 函數名(參數列表)(傳回值列表)2 {3 //函數體4 }
其實可以發現左括弧放在傳回值列表後面是有一個好的地方是:在很多編輯器裡面,比如notepad,它把左括弧和右括弧之間用線連起來,顯得是一個整體,如果把左括弧單獨起一行,會顯得函數定義時候func行不與函數體一起,而把左大括弧放在func行,會顯得整個函數渾然一體。
3.2若干命令
查看go版本
cmd —— go version輸出 go version go1.0.3
編譯來源程式
go build HelloWorld.go
運行編譯後代碼
HelloWorld.exe
函數的單元測試
xxx.go對應的單元測試是xxx_test.go,這是go工程裡的命名規則
2. 順序編程
2.1 變數
從根本上說,變數是對一塊資料存放區空間的命名,程式可以通過定義一個變數來申請一塊資料存放區空間,之後通過調用(引用)變數名來使用這Block Storage空間
2.1.1 變數定義
Go語言的變數聲明方式與其他語言相差比較大。引入了一個關鍵字var(但不是必須的),表示一個變數
定義文法
var 變數名 變數類型
樣本:var name string
這種方式其實更符合英語習慣 可以把上面的定義方式擴充成英語:the variable name is a string 變數name是一個string,如果去掉動詞、量詞就可以看出var name string 比較近似我們平時使用的英語文法結構。
類似地:
1 var v1 int 2 var v2 string 3 var v3 [10]int //定義一個固定長度的數組 4 var v4 []int //定義一個可變長度的數組 5 var v5 struct{ 6 f int 7 } 8 var v6 *int //指標 9 var v7 map[string]int //字典,或者說關聯陣列與Java的map類似,key為string類型,value為int類型10 var v8 func(a int) int
變數塊
可以使用var關鍵字聲明若干個關鍵字,形成一個變數塊
1 var(2 v1 int3 v2 string4 )
從上面多出的var關鍵字可以看出,有一個var關鍵字更加符合英語習慣,不僅如此,可以同時聲明多個變數,把變數用一個關鍵字var包起來,形成一個整塊,這樣可讀性更好,不會讓變數亂放。
2.1.2變數賦值
1 //定義一個變數2 var v1 int3 //對一個變數初始化賦值4 v1 = 10
上面的兩步可以合成,也就是定義加初始化用一個陳述式完成。
有三種方式
1 var v1 int = 10 //正確使用方式12 var v2 = 10 //正確使用方式2,編譯器可以自動推匯出v2的類型3 v3 := 10 //正確使用方式3,編譯器可以自動推導v3的類型
:=這個運算子包含了定義和初始化兩步操作。出現這個運算子的變數不應該是已經被定義過的,否則會編譯錯誤。
指定變數類型不是必須的,看起來有點像動態類型語言。但實際是靜態語言。
Go語言提供了多重賦值功能,例如進行i,j的值交換,這樣可以避免很多無關的變數都定義了,影響代碼可讀性
i,j = j,i
2.1.3匿名變數
我們在使用傳統的強型別語言編程時,經常會出現這種情況,即在調用函數時為了擷取一個值,卻因為該函數返回多個值而不得不定義一堆沒用的變數。在Go中這種情況可以通過結合使
用多重返回和匿名變數來避免這種醜陋的寫法,讓代碼看起來更加優雅。
2.2 常量
常量是指編譯期間已知且不可改變的值,常量可以是數實值型別(包括整型、浮點型和複數類型)、布爾類型、字串類型
2.2.1 字面常量
字面常量是指程式中硬式編碼常量,如
無類型 2 //由於2在許多數實值型別定義域內,並且沒有規定2的類型,因此是一個無類型,當然也可以指定2L,是一個long型的
浮點型 3.1415926
複數型 3.2+12i
布爾型 true
字串 "true"
2.2.2常量定義
通過const關鍵字,可以指定字面常量名字
1 const Pi float64 = 3.14324234242342 const zero = 0.03 const(4 size int64 = 10245 eof = -1//無類型整型常量6 )7 const u,v float32 = 0.3 //定義多重賦值8 const a,b,c = 3,4,"true" //a = 3,b = 4,c = "true",無類型整型和字串常量
常量定義的右值也可以是一個編譯期運算的常量運算式
const mask = 1 <<3
常量的賦值是一個編譯期行為,所以右值不能出現任何需要運行期才能得出結果的運算式(否則就不是常量了)
下面的例子就會導致編譯錯誤,常量就是運行前就已經確定的值。
const Home = os.GetEnv("HOME")
2.2.3 預定義常量
Go語言預定義了這些常量true、false和iota.iota比較特殊,可以被認為是一個可被編譯器修改的常量,在每一個const關鍵字出現時被重設為0,然後在下一個const出現之前,每出現一次iota,其所代表的數字會自動增1。
從以下的例子可以基本理解iota的用法:
1 const ( // iota被重設為0 2 c0 = iota // c0 == 0 3 c1 = iota // c1 == 1 4 c2 = iota // c2 == 2 5 ) 6 7 const ( 8 a = 1 << iota // a == 1 (iota在每個const開頭被重設為0) 9 b = 1 << iota // b == 2 10 c = 1 << iota // c == 4 11 ) 12 13 const ( 14 u = iota * 42 // u == 0 15 v float64 = iota * 42 // v == 42.0 16 w = iota * 42 // w == 84 17 ) 18 const x = iota // x == 0 (因為iota又被重設為0了) 19 const y = iota // y == 0 (同上)
如果兩個const的指派陳述式的運算式是一樣的,那麼可以省略後一個賦值運算式。因此,上面的前兩個const語句可簡寫為:
1 const ( // iota被重設為0 2 c0 = iota // c0 == 0 3 c1 // c1 == 1 4 c2 // c2 == 2 5 ) 6 7 const ( 8 a = 1 <<iota // a == 1 (iota在每個const開頭被重設為0) 9 b // b == 2 10 c // c == 4 11 )
個人認為iota未必是一個好的資料類型
2.2.4枚舉
枚舉指一系列相關的常量,比如下面關於一個星期中每天的定義。通過上一節的例子,我們看到可以用在const後跟一對圓括弧的方式定義一組常量,這種定義法在Go語言中通常用於定義
枚舉值。Go語言並不支援眾多其他語言明確支援的enum關鍵字。
下面是一個常規的枚舉標記法,其中定義了一系列整型常量:
1 const ( 2 Sunday = iota 3 Monday 4 Tuesday 5 Wednesday 6 Thursday 7 Friday 8 Saturday 9 numberOfDays // 這個常量沒有匯出 10 )
同Go語言的其他符號(symbol)一樣,以大寫字母開頭的常量在包外可見。 以上例子中numberOfDays為包內私人,其他符號則可被其他包訪問。
2.3 資料類型
Go支援如下資料類型