Go 语言学习
菜鳥教程 - Go語言教程:http://www.runoob.com/go/go-tutorial.html
Go語言入門教程,Golang入門教程(非常詳細(xì)):http://c.biancheng.net/golang
易百 - Go語言教程:https://www.yiibai.com/go
《Go入門指南》電子書:https://www.kancloud.cn/kancloud/the-way-to-go/72432
笨鳥學(xué)Go——最簡單的Go教程:http://www.slowbirdgogogo.com/????
Go 語言相關(guān)書籍:京東搜索 go 的相關(guān)書籍
?
Microsoft Visual Studio Code:https://blog.csdn.net/freeking101/article/details/86715578
?
?
打算開始學(xué)習(xí) go 語言,就搜了下go 的資料,先按上面鏈接把 Go 語言基礎(chǔ)過一遍。最好按 一個(gè)網(wǎng)站來看,比如把 菜鳥教程上面 Go語言教程 從頭看到尾。然后在看其他網(wǎng)站教程,這時(shí)候可以不像 看 菜鳥網(wǎng)上教程那么仔細(xì),但是注意多寫程序練習(xí)。
上面都看完之后,可以找一些實(shí)戰(zhàn)項(xiàng)目練習(xí)下,或者把以前用 Python 寫的爬蟲用 go 在重寫下。
?
?
GO 語言新手:8個(gè)實(shí)戰(zhàn)教程:
基礎(chǔ)教程:
-
Go語言編程
-
Go by Example 中文版
實(shí)戰(zhàn)項(xiàng)目:
-
《 Go 語言實(shí)戰(zhàn) 》 快速開始一個(gè) Go 程序
-
GO語言開發(fā)2048
-
GO語言制作Markdown預(yù)覽器
-
基于GO語言Revel框架和mgo的博客
-
Go 語言實(shí)現(xiàn)緩存系統(tǒng)
-
Go 語言實(shí)現(xiàn)WebSocket協(xié)議
最后:
希望以上8個(gè)教程能給你學(xué)習(xí)GO語言有所幫助,如果你想要學(xué)習(xí)其他技術(shù)領(lǐng)域,可以看下面:
- 學(xué)習(xí)路徑:12條技術(shù)路徑,照著路徑系統(tǒng)學(xué)習(xí),入門該領(lǐng)域;
- 海量教程:基礎(chǔ)、實(shí)戰(zhàn)項(xiàng)目,各技術(shù)領(lǐng)域應(yīng)有盡有,更有在線開發(fā)環(huán)境隨時(shí)玩;
- 挑戰(zhàn)比賽:學(xué)完之后,參加挑戰(zhàn),看看自己水平如何,更可以參加比賽,PK實(shí)力;’
?
?
Go 語言環(huán)境安裝
?
安裝包下載地址為:https://golang.org/dl/。
如果打不開可以使用這個(gè)地址:https://golang.google.cn/dl/。
各個(gè)系統(tǒng)對(duì)應(yīng)的包名:
| Windows | go1.4.windows-amd64.msi |
| Linux | go1.4.linux-amd64.tar.gz |
| Mac | go1.4.darwin-amd64-osx10.8.pkg |
| FreeBSD | go1.4.freebsd-amd64.tar.gz |
?
UNIX/Linux/Mac OS X, 和 FreeBSD 安裝
以下介紹了在UNIX/Linux/Mac OS X, 和 FreeBSD系統(tǒng)下使用源碼安裝方法:
1、下載二進(jìn)制包:go1.4.linux-amd64.tar.gz。
2、將下載的二進(jìn)制包解壓至 /usr/local目錄。
tar -C /usr/local -xzf go1.4.linux-amd64.tar.gz3、將 /usr/local/go/bin 目錄添加至PATH環(huán)境變量:
export PATH=$PATH:/usr/local/go/bin注意:MAC 系統(tǒng)下你可以使用?.pkg?結(jié)尾的安裝包直接雙擊來完成安裝,安裝目錄在?/usr/local/go/?下。
Windows 系統(tǒng)下安裝
Windows 下可以使用 .msi 后綴(在下載列表中可以找到該文件,如go1.4.2.windows-amd64.msi)的安裝包來安裝。
默認(rèn)情況下.msi文件會(huì)安裝在 c:\Go 目錄下。你可以將 c:\Go\bin 目錄添加到 PATH 環(huán)境變量中。添加后你需要重啟命令窗口才能生效。
安裝測(cè)試
創(chuàng)建工作目錄 C:\>Go_WorkSpace。
文件名: test.go,代碼如下:
package mainimport "fmt"func main() {fmt.Println("Hello, World!") }使用 go 命令執(zhí)行以上代碼輸出結(jié)果如下:
C:\Go_WorkSpace>go run test.go
Hello, World!
?
?
?
Go 語言結(jié)構(gòu)
?
Go 語言的基礎(chǔ)組成有以下幾個(gè)部分:
- 包聲明
- 引入包
- 函數(shù)
- 變量
- 語句 & 表達(dá)式
- 注釋
接下來讓我們來看下簡單的代碼,該代碼輸出了"Hello World!":
package mainimport "fmt"func main() {/* 這是我的第一個(gè)簡單的程序 */fmt.Println("Hello, World!") }看下以上程序的各個(gè)部分:
第一行代碼?package main?定義了包名。你必須在源文件中非注釋的第一行指明這個(gè)文件屬于哪個(gè)包,如:package main。package main表示一個(gè)可獨(dú)立執(zhí)行的程序,每個(gè) Go 應(yīng)用程序都包含一個(gè)名為 main 的包。
下一行?import "fmt"?告訴 Go 編譯器這個(gè)程序需要使用 fmt 包(的函數(shù),或其他元素),fmt 包實(shí)現(xiàn)了格式化 IO(輸入/輸出)的函數(shù)。
下一行?func main()?是程序開始執(zhí)行的函數(shù)。main 函數(shù)是每一個(gè)可執(zhí)行程序所必須包含的,一般來說都是在啟動(dòng)后第一個(gè)執(zhí)行的函數(shù)(如果有 init() 函數(shù)則會(huì)先執(zhí)行該函數(shù))。
下一行 /*...*/ 是注釋,在程序執(zhí)行時(shí)將被忽略。單行注釋是最常見的注釋形式,你可以在任何地方使用以 // 開頭的單行注釋。多行注釋也叫塊注釋,均已以 /* 開頭,并以 */ 結(jié)尾,且不可以嵌套使用,多行注釋一般用于包的文檔描述或注釋成塊的代碼片段。
下一行?fmt.Println(...)?可以將字符串輸出到控制臺(tái),并在最后自動(dòng)增加換行字符 \n。?
使用 fmt.Print("hello, world\n") 可以得到相同的結(jié)果。?
Print 和 Println 這兩個(gè)函數(shù)也支持使用變量,如:fmt.Println(arr)。如果沒有特別指定,它們會(huì)以默認(rèn)的打印格式將變量 arr 輸出到控制臺(tái)。
當(dāng)標(biāo)識(shí)符(包括常量、變量、類型、函數(shù)名、結(jié)構(gòu)字段等等)以一個(gè)大寫字母開頭,如:Group1,那么使用這種形式的標(biāo)識(shí)符的對(duì)象就可以被外部包的代碼所使用(客戶端程序需要先導(dǎo)入這個(gè)包),這被稱為導(dǎo)出(像面向?qū)ο笳Z言中的 public);標(biāo)識(shí)符如果以小寫字母開頭,則對(duì)包外是不可見的,但是他們?cè)谡麄€(gè)包的內(nèi)部是可見并且可用的(像面向?qū)ο笳Z言中的 protected )。
?
執(zhí)行 Go 程序
讓我們來看下如何編寫 Go 代碼并執(zhí)行它。步驟如下:
打開編輯器如Sublime2,將以上代碼添加到編輯器中。
將以上代碼保存為?hello.go
打開命令行,并進(jìn)入程序文件保存的目錄中。
輸入命令?go run hello.go?并按回車執(zhí)行代碼。
如果操作正確你將在屏幕上看到?"Hello World!"?字樣的輸出。
$ go run hello.go
Hello, World!
?
注意
需要注意的是?{?不能單獨(dú)放在一行,所以以下代碼在運(yùn)行時(shí)會(huì)產(chǎn)生錯(cuò)誤:
package mainimport "fmt"func main() { // 錯(cuò)誤,{ 不能在單獨(dú)的行上fmt.Println("Hello, World!") }?
?
?
Learn X in Y minutes
?
Go語言有非常棒的標(biāo)準(zhǔn)庫,還有一個(gè)充滿熱情的社區(qū)。
// 單行注釋 /* 多行注釋 */// 導(dǎo)入包的子句在每個(gè)源文件的開頭。 // Main比較特殊,它用來聲明可執(zhí)行文件,而不是一個(gè)庫。 package main// Import語句聲明了當(dāng)前文件引用的包。 import ("fmt" // Go語言標(biāo)準(zhǔn)庫中的包"io/ioutil" // 包含一些輸入輸出函數(shù)m "math" // 數(shù)學(xué)標(biāo)準(zhǔn)庫,在此文件中別名為m"net/http" // 一個(gè)web服務(wù)器包"os" // 系統(tǒng)底層函數(shù),如文件讀寫"strconv" // 字符串轉(zhuǎn)換 )// 函數(shù)聲明:Main是程序執(zhí)行的入口。 // 不管你喜歡還是不喜歡,反正Go就用了花括號(hào)來包住函數(shù)體。 func main() {// 往標(biāo)準(zhǔn)輸出打印一行。// 用包名fmt限制打印函數(shù)。fmt.Println("天坑歡迎你!")// 調(diào)用當(dāng)前包的另一個(gè)函數(shù)。beyondHello() }// 函數(shù)可以在括號(hào)里加參數(shù)。 // 如果沒有參數(shù)的話,也需要一個(gè)空括號(hào)。 func beyondHello() {var x int // 變量聲明,變量必須在使用之前聲明。x = 3 // 變量賦值。// 可以用:=來偷懶,它自動(dòng)把變量類型、聲明和賦值都搞定了。y := 4sum, prod := learnMultiple(x, y) // 返回多個(gè)變量的函數(shù)fmt.Println("sum:", sum, "prod:", prod) // 簡單輸出learnTypes() // 少于y分鐘,學(xué)的更多! }/* <- 快看快看我是跨行注釋_(:з」∠)_ Go語言的函數(shù)可以有多個(gè)參數(shù)和 *多個(gè)* 返回值。 在這個(gè)函數(shù)中, `x`、`y` 是參數(shù), `sum`、`prod` 是返回值的標(biāo)識(shí)符(可以理解為名字)且類型為int */ func learnMultiple(x, y int) (sum, prod int) {return x + y, x * y // 返回兩個(gè)值 }// 內(nèi)置變量類型和關(guān)鍵詞 func learnTypes() {// 短聲明給你所想。str := "少說話多讀書!" // String類型s2 := `這是一個(gè) 可以換行的字符串` // 同樣是String類型// 非ascii字符。Go使用UTF-8編碼。g := 'Σ' // rune類型,int32的別名,使用UTF-8編碼f := 3.14195 // float64類型,IEEE-754 64位浮點(diǎn)數(shù)c := 3 + 4i // complex128類型,內(nèi)部使用兩個(gè)float64表示// Var變量可以直接初始化。var u uint = 7 // unsigned 無符號(hào)變量,但是實(shí)現(xiàn)依賴int型變量的長度var pi float32 = 22. / 7// 字符轉(zhuǎn)換n := byte('\n') // byte是uint8的別名// 數(shù)組(Array)類型的大小在編譯時(shí)即確定var a4 [4] int // 有4個(gè)int變量的數(shù)組,初始為0a3 := [...]int{3, 1, 5} // 有3個(gè)int變量的數(shù)組,同時(shí)進(jìn)行了初始化// Array和slice各有所長,但是slice可以動(dòng)態(tài)的增刪,所以更多時(shí)候還是使用slice。s3 := []int{4, 5, 9} // 回去看看 a3 ,是不是這里沒有省略號(hào)?s4 := make([]int, 4) // 分配4個(gè)int大小的內(nèi)存并初始化為0var d2 [][]float64 // 這里只是聲明,并未分配內(nèi)存空間bs := []byte("a slice") // 進(jìn)行類型轉(zhuǎn)換// 切片(Slice)的大小是動(dòng)態(tài)的,它的長度可以按需增長// 用內(nèi)置函數(shù) append() 向切片末尾添加元素// 要增添到的目標(biāo)是 append 函數(shù)第一個(gè)參數(shù),// 多數(shù)時(shí)候數(shù)組在原內(nèi)存處順次增長,如s := []int{1, 2, 3} // 這是個(gè)長度3的slices = append(s, 4, 5, 6) // 再加仨元素,長度變?yōu)?了fmt.Println(s) // 更新后的數(shù)組是 [1 2 3 4 5 6]// 除了向append()提供一組原子元素(寫死在代碼里的)以外,我們// 還可以用如下方法傳遞一個(gè)slice常量或變量,并在后面加上省略號(hào),// 用以表示我們將引用一個(gè)slice、解包其中的元素并將其添加到s數(shù)組末尾。s = append(s, []int{7, 8, 9}...) // 第二個(gè)參數(shù)是一個(gè)slice常量fmt.Println(s) // 更新后的數(shù)組是 [1 2 3 4 5 6 7 8 9]p, q := learnMemory() // 聲明p,q為int型變量的指針fmt.Println(*p, *q) // * 取值// Map是動(dòng)態(tài)可增長關(guān)聯(lián)數(shù)組,和其他語言中的hash或者字典相似。m := map[string]int{"three": 3, "four": 4}m["one"] = 1// 在Go語言中未使用的變量在編譯的時(shí)候會(huì)報(bào)錯(cuò),而不是warning。// 下劃線 _ 可以使你“使用”一個(gè)變量,但是丟棄它的值。_, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs// 通常的用法是,在調(diào)用擁有多個(gè)返回值的函數(shù)時(shí),// 用下劃線拋棄其中的一個(gè)參數(shù)。下面的例子就是一個(gè)臟套路,// 調(diào)用os.Create并用下劃線變量扔掉它的錯(cuò)誤代碼。// 因?yàn)槲覀冇X得這個(gè)文件一定會(huì)成功創(chuàng)建。file, _ := os.Create("output.txt")fmt.Fprint(file, "這句代碼還示范了如何寫入文件呢")file.Close()// 輸出變量fmt.Println(s, c, a4, s3, d2, m)learnFlowControl() // 回到流程控制 }// 和其他編程語言不同的是,go支持有名稱的變量返回值。 // 聲明返回值時(shí)帶上一個(gè)名字允許我們?cè)诤瘮?shù)內(nèi)的不同位置 // 只用寫return一個(gè)詞就能將函數(shù)內(nèi)指定名稱的變量返回 func learnNamedReturns(x, y int) (z int) {z = x * yreturn // z is implicit here, because we named it earlier. }// Go全面支持垃圾回收。Go有指針,但是不支持指針運(yùn)算。 // 你會(huì)因?yàn)榭罩羔樁稿e(cuò),但是不會(huì)因?yàn)樵黾又羔樁稿e(cuò)。 func learnMemory() (p, q *int) {// 返回int型變量指針p和qp = new(int) // 內(nèi)置函數(shù)new分配內(nèi)存// 自動(dòng)將分配的int賦值0,p不再是空的了。s := make([]int, 20) // 給20個(gè)int變量分配一塊內(nèi)存s[3] = 7 // 賦值r := -2 // 聲明另一個(gè)局部變量return &s[3], &r // & 取地址 }func expensiveComputation() int {return 1e6 }func learnFlowControl() {// If需要花括號(hào),括號(hào)就免了if true {fmt.Println("這句話肯定被執(zhí)行")}// 用go fmt 命令可以幫你格式化代碼,所以不用怕被人吐槽代碼風(fēng)格了,// 也不用容忍別人的代碼風(fēng)格。if false {// pout} else {// gloat}// 如果太多嵌套的if語句,推薦使用switchx := 1switch x {case 0:case 1:// 隱式調(diào)用break語句,匹配上一個(gè)即停止case 2:// 不會(huì)運(yùn)行}// 和if一樣,for也不用括號(hào)for x := 0; x < 3; x++ { // ++ 自增fmt.Println("遍歷", x)}// x在這里還是1。為什么?// for 是go里唯一的循環(huán)關(guān)鍵字,不過它有很多變種for { // 死循環(huán)break // 騙你的continue // 不會(huì)運(yùn)行的}// 用range可以枚舉 array、slice、string、map、channel等不同類型// 對(duì)于channel,range返回一個(gè)值,// array、slice、string、map等其他類型返回一對(duì)兒for key, value := range map[string]int{"one": 1, "two": 2, "three": 3} {// 打印map中的每一個(gè)鍵值對(duì)fmt.Printf("索引:%s, 值為:%d\n", key, value)}// 如果你只想要值,那就用前面講的下劃線扔掉沒用的for _, name := range []string{"Bob", "Bill", "Joe"} {fmt.Printf("你是。。 %s\n", name)}// 和for一樣,if中的:=先給y賦值,然后再和x作比較。if y := expensiveComputation(); y > x {x = y}// 閉包函數(shù)xBig := func() bool {return x > 100 // x是上面聲明的變量引用}fmt.Println("xBig:", xBig()) // true (上面把y賦給x了)x /= 1e5 // x變成10fmt.Println("xBig:", xBig()) // 現(xiàn)在是false// 除此之外,函數(shù)體可以在其他函數(shù)中定義并調(diào)用,// 滿足下列條件時(shí),也可以作為參數(shù)傳遞給其他函數(shù):// a) 定義的函數(shù)被立即調(diào)用// b) 函數(shù)返回值符合調(diào)用者對(duì)類型的要求fmt.Println("兩數(shù)相加乘二: ",func(a, b int) int {return (a + b) * 2}(10, 2)) // Called with args 10 and 2// => Add + double two numbers: 24// 當(dāng)你需要goto的時(shí)候,你會(huì)愛死它的!goto love love:learnFunctionFactory() // 返回函數(shù)的函數(shù)多棒啊learnDefer() // 對(duì)defer關(guān)鍵字的簡單介紹learnInterfaces() // 好東西來了! }func learnFunctionFactory() {// 空行分割的兩個(gè)寫法是相同的,不過第二個(gè)寫法比較實(shí)用fmt.Println(sentenceFactory("原諒")("當(dāng)然選擇", "她!"))d := sentenceFactory("原諒")fmt.Println(d("當(dāng)然選擇", "她!"))fmt.Println(d("你怎么可以", "她?")) }// Decorator在一些語言中很常見,在go語言中, // 接受參數(shù)作為其定義的一部分的函數(shù)是修飾符的替代品 func sentenceFactory(mystring string) func(before, after string) string {return func(before, after string) string {return fmt.Sprintf("%s %s %s", before, mystring, after) // new string} }func learnDefer() (ok bool) {// defer表達(dá)式在函數(shù)返回的前一刻執(zhí)行defer fmt.Println("defer表達(dá)式執(zhí)行順序?yàn)楹筮M(jìn)先出(LIFO)")defer fmt.Println("\n這句話比上句話先輸出,因?yàn)?#34;)// 關(guān)于defer的用法,例如用defer關(guān)閉一個(gè)文件,// 就可以讓關(guān)閉操作與打開操作的代碼更近一些return true }// 定義Stringer為一個(gè)接口類型,有一個(gè)方法String type Stringer interface {String() string }// 定義pair為一個(gè)結(jié)構(gòu)體,有x和y兩個(gè)int型變量。 type pair struct {x, y int }// 定義pair類型的方法,實(shí)現(xiàn)Stringer接口。 func (p pair) String() string { // p被叫做“接收器”// Sprintf是fmt包中的另一個(gè)公有函數(shù)。// 用 . 調(diào)用p中的元素。return fmt.Sprintf("(%d, %d)", p.x, p.y) }func learnInterfaces() {// 花括號(hào)用來定義結(jié)構(gòu)體變量,:=在這里將一個(gè)結(jié)構(gòu)體變量賦值給p。p := pair{3, 4}fmt.Println(p.String()) // 調(diào)用pair類型p的String方法var i Stringer // 聲明i為Stringer接口類型i = p // 有效!因?yàn)閜實(shí)現(xiàn)了Stringer接口(類似java中的塑型)// 調(diào)用i的String方法,輸出和上面一樣fmt.Println(i.String())// fmt包中的Println函數(shù)向?qū)ο笠鼈兊膕tring輸出,實(shí)現(xiàn)了String方法就可以這樣使用了。// (類似java中的序列化)fmt.Println(p) // 輸出和上面一樣,自動(dòng)調(diào)用String函數(shù)。fmt.Println(i) // 輸出和上面一樣。learnVariadicParams("great", "learning", "here!") }// 有變長參數(shù)列表的函數(shù) func learnVariadicParams(myStrings ...interface{}) {// 枚舉變長參數(shù)列表的每個(gè)參數(shù)值// 下劃線在這里用來拋棄枚舉時(shí)返回的數(shù)組索引值for _, param := range myStrings {fmt.Println("param:", param)}// 將可變參數(shù)列表作為其他函數(shù)的參數(shù)列表fmt.Println("params:", fmt.Sprintln(myStrings...))learnErrorHandling() }func learnErrorHandling() {// ", ok"用來判斷有沒有正常工作m := map[int]string{3: "three", 4: "four"}if x, ok := m[1]; !ok { // ok 為false,因?yàn)閙中沒有1fmt.Println("別找了真沒有")} else {fmt.Print(x) // 如果x在map中的話,x就是那個(gè)值嘍。}// 錯(cuò)誤可不只是ok,它還可以給出關(guān)于問題的更多細(xì)節(jié)。if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value// 輸出"strconv.ParseInt: parsing "non-int": invalid syntax"fmt.Println(err)}// 待會(huì)再說接口吧。同時(shí),learnConcurrency() }// c是channel類型,一個(gè)并發(fā)安全的通信對(duì)象。 func inc(i int, c chan int) {c <- i + 1 // <-把右邊的發(fā)送到左邊的channel。 }// 我們將用inc函數(shù)來并發(fā)地增加一些數(shù)字。 func learnConcurrency() {// 用make來聲明一個(gè)slice,make會(huì)分配和初始化slice,map和channel。c := make(chan int)// 用go關(guān)鍵字開始三個(gè)并發(fā)的goroutine,如果機(jī)器支持的話,還可能是并行執(zhí)行。// 三個(gè)都被發(fā)送到同一個(gè)channel。go inc(0, c) // go is a statement that starts a new goroutine.go inc(10, c)go inc(-805, c)// 從channel中讀取結(jié)果并打印。// 打印出什么東西是不可預(yù)知的。fmt.Println(<-c, <-c, <-c) // channel在右邊的時(shí)候,<-是讀操作。cs := make(chan string) // 操作string的channelcc := make(chan chan string) // 操作channel的channelgo func() { c <- 84 }() // 開始一個(gè)goroutine來發(fā)送一個(gè)新的數(shù)字go func() { cs <- "wordy" }() // 發(fā)送給cs// Select類似于switch,但是每個(gè)case包括一個(gè)channel操作。// 它隨機(jī)選擇一個(gè)準(zhǔn)備好通訊的case。select {case i := <-c: // 從channel接收的值可以賦給其他變量fmt.Println("這是……", i)case <-cs: // 或者直接丟棄fmt.Println("這是個(gè)字符串!")case <-cc: // 空的,還沒作好通訊的準(zhǔn)備fmt.Println("別瞎想")}// 上面c或者cs的值被取到,其中一個(gè)goroutine結(jié)束,另外一個(gè)一直阻塞。learnWebProgramming() // Go很適合web編程,我知道你也想學(xué)! }// http包中的一個(gè)簡單的函數(shù)就可以開啟web服務(wù)器。 func learnWebProgramming() {// ListenAndServe第一個(gè)參數(shù)指定了監(jiān)聽端口,第二個(gè)參數(shù)是一個(gè)接口,特定是http.Handler。go func() {err := http.ListenAndServe(":8080", pair{})fmt.Println(err) // 不要無視錯(cuò)誤。}()requestServer() }// 使pair實(shí)現(xiàn)http.Handler接口的ServeHTTP方法。 func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {// 使用http.ResponseWriter返回?cái)?shù)據(jù)w.Write([]byte("Y分鐘golang速成!")) }func requestServer() {resp, err := http.Get("http://localhost:8080")fmt.Println(err)defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)fmt.Printf("\n服務(wù)器消息: `%s`", string(body)) }更進(jìn)一步
關(guān)于Go的一切你都可以在Go官方網(wǎng)站找到。 在那里你可以獲得教程參考,在線試用,和更多的資料。 在簡單的嘗試過后,在官方文檔那里你會(huì)得到你所需要的所有資料、關(guān)于編寫代碼的規(guī)范、庫和命令行工具的文檔與Go的版本歷史。
強(qiáng)烈推薦閱讀語言定義部分,很簡單而且很簡潔!(趕時(shí)髦!)
你還可以前往Go在線體驗(yàn)中心進(jìn),在瀏覽器里修改并運(yùn)行這些代碼,一定要試一試哦!你可以將https://play.golang.org當(dāng)作一個(gè)REPL,在那里體驗(yàn)語言特性或運(yùn)行自己的代碼,連環(huán)境都不用配!
學(xué)習(xí)Go還要閱讀Go標(biāo)準(zhǔn)庫的源代碼,全部文檔化了,可讀性非常好,可以學(xué)到go,go style和go idioms。在文檔中點(diǎn)擊函數(shù)名,源代碼就出來了!
Go by example也是一個(gè)學(xué)習(xí)的好地方。
Go Mobile添加了對(duì)移動(dòng)平臺(tái)的支持(Android and iOS)。你可以完全用go語言來創(chuàng)造一個(gè)app或編寫一個(gè)可以從Java或Obj-C調(diào)用的函數(shù)庫,敬請(qǐng)參考Go Mobile page。
?
?
?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
- 上一篇: 8个最高效的Python爬虫框架,你用过
- 下一篇: Hamcrest总结--思维导图