加 Golang學習 QQ群共同學習進步成家立業工作 ^-^ 群號:96933959
簡介
Go是Google開發的一種 靜態強類型、編譯型,並發型,並具有垃圾回收功能的編程語言。為了方便搜索和識別,有時會將其稱為Golang。
羅伯特·格瑞史莫,羅勃·派克(Rob Pike)及肯·湯普遜於2007年9月開始設計Go語言,稍后Ian Lance Taylor、Russ Cox加入項目。Go語言是基於Inferno操作系統所開發的。Go語言於2009年11月正式宣布推出,成為開放源代碼項目,並在Linux及Mac OS X平台上進行了實現,后來追加了Windows系統下的實現。在2012年早些時候發布了Go 1穩定版本。
現在Go的開發已經是完全開放的,並且擁有一個活躍的社區。
Go語言的語法接近C語言,但對於變量的聲明有所不同。Go語言支持垃圾回收功能。Go語言的並行模型是以東尼·霍爾的通信順序進程(CSP)為基礎,采取類似模型的其他語言包括Occam和Limbo,但它也具有Pi運算的特征,比如通道傳輸。在1.8版本中開放插件(Plugin)的支持,這意味着現在能從Go語言中動態加載部分函數。
與C++相比,Go語言並不包括如異常處理、繼承、泛型、斷言、虛函數等功能,但增加了 Slice 型、並發、管道、垃圾回收、接口(Interface)等特性的語言級支持。Google 目前仍正在討論是否應該支持泛型,其態度還是很開放的,但在該語言的常見問題列表中,對於斷言的存在,則持負面態度,同時也為自己不提供類型繼承來辯護。
不同於Java,Go語言內嵌了關聯數組(也稱為哈希表(Hashes)或字典(Dictionaries)),就像字符串類型一樣。
語言特性
1. 垃圾回收
- 內存自動回收,再也不需要開發人員管理內存
-
只需要new分配內存,不需要釋放
2. 天然並發
- 從語言層面支持並發,非常簡單
-
Goroutine,輕量級線程,創建成千上萬個Goroutine成為可能
-
基於CSP(Communicating Sequential Process)模型實現
3. channel
- 管道,類似unix/linux中的pipe
-
多個Goroutine之間通過channel進行通信
-
支持任何類型
-
close 內置函數用來關閉 channel
4. Goroutine
Go語言的主要的功能在於令人簡易使用的並行設計,這個方法叫做Goroutine,通過Goroutine能夠讓你的程序以異步的方式運行,而不需要擔心一個函數導致程序中斷,因此Go語言也非常地適合網絡服務。
Goroutine是類似線程的概念(但Goroutine並不是線程)。線程屬於系統層面,通常來說創建一個新的線程會消耗較多的資源且管理不易。而 Goroutine就像輕量級的線程,但我們稱其為並發,一個Go程序可以運行超過數萬個 Goroutine,並且這些性能都是原生級的,隨時都能夠關閉、結束。一個核心里面可以有多個Goroutine,通過GOMAXPROCS參數你能夠限制Gorotuine可以占用幾個系統線程來避免失控。
在內置的官方包中也不時能夠看見Goroutine的應用,像是net/http中用來監聽網絡服務的函數實際上是創建一個不斷運行循環的Goroutine。
編譯器
當前有兩個Go語言的編譯器的分支。官方編譯器gc和gccgo。官方編譯器在初期使用C寫成,后用go重寫從而實現自舉。Gccgo是一個使用標准GCC作為后端的Go編譯器。
官方編譯器支持跨平台編譯(但不支持CGO),允許將源碼編譯為可在目標系統、架構上執行的二進制文件。
安裝
設置環境變量:
- export GOROOT=$PATH:/path/to/go/
- export PATH=$PATH:$GOROOT/bin/
- export GOPATH=/home/user/project/go
終端測試:
- go version
- go env
-
Gofmt -w *.go
IDE安裝可參考:
go 標准命令
go build
go build
命令用於編譯我們指定的源碼文件或代碼包以及它們的依賴包
go build -o bin/tongbupan go_dev/tongbupan/main
-o :指定編譯后存放目錄以及名稱
go install
go install
用於編譯並安裝指定的代碼包及它們的依賴包。
go get
go get
可以根據要求和實際情況從互聯網上下載或更新指定的代碼包及其依賴包,並對它們進行編譯和安裝。
go clean
go clean
命令會刪除掉執行其它命令時產生的一些文件和目錄
go doc & godoc
go doc
命令可以打印附於Go語言程序實體上的文檔。我們可以通過把程序實體的標識符作為該命令的參數來達到查看其文檔的目的。
godoc
是一個很強大的工具,同樣用於展示指定代碼包的文檔。
go run
go run
命令可以編譯並運行命令源碼文件。
go run src/go_dev/hello.go
標記名稱 | 標記描述 |
---|---|
-a | 強行對所有涉及到的代碼包(包含標准庫中的代碼包)進行重新構建,即使它們已經是最新的了。 |
-n | 打印編譯期間所用到的其它命令,但是並不真正執行它們。 |
-p n | 指定編譯過程中執行各任務的並行數量(確切地說應該是並發數量)。在默認情況下,該數量等於CPU的邏輯核數。但是在darwin/arm 平台(即iPhone和iPad所用的平台)下,該數量默認是1 。 |
-race | 開啟競態條件的檢測。不過此標記目前僅在linux/amd64 、freebsd/amd64 、darwin/amd64 和windows/amd64 平台下受到支持。 |
-v | 打印出那些被編譯的代碼包的名字。 |
-work | 打印出編譯時生成的臨時工作目錄的路徑,並在編譯結束時保留它。在默認情況下,編譯結束時會刪除該目錄。 |
-x | 打印編譯期間所用到的其它命令。注意它與-n 標記的區別。 |
go test
go test
命令用於對Go語言編寫的程序進行測試。這種測試是以代碼包為單位的。
go list
go list
命令的作用是列出指定的代碼包的信息。
go fix與go tool fix
go fix
會把指定代碼包的所有Go語言源碼文件中的舊版本代碼修正為新版本的代碼。
命令go fix
其實是命令go tool fix
的簡單封裝。
go vet與go tool vet
go vet
是一個用於檢查Go語言源碼中靜態錯誤的簡單工具。
go vet
命令是go tool vet
命令的簡單封裝。
go tool pprof
go tool pprof
命令來交互式的訪問概要文件的內容。
go tool cgo
可以使我們創建能夠調用C語言代碼的Go語言源碼文件。
go env
go env
用於打印Go語言的環境信息。
名稱 | 說明 |
---|---|
CGO_ENABLED | 指明cgo工具是否可用的標識。 |
GOARCH | 程序構建環境的目標計算架構。 |
GOBIN | 存放可執行文件的目錄的絕對路徑。 |
GOCHAR | 程序構建環境的目標計算架構的單字符標識。 |
GOEXE | 可執行文件的后綴。 |
GOHOSTARCH | 程序運行環境的目標計算架構。 |
GOOS | 程序構建環境的目標操作系統。 |
GOHOSTOS | 程序運行環境的目標操作系統。 |
GOPATH | 工作區目錄的絕對路徑。 |
GORACE | 用於數據競爭檢測的相關選項。 |
GOROOT | Go語言的安裝目錄的絕對路徑。 |
GOTOOLDIR | Go工具目錄的絕對路徑。 |
Hello World
package main import "fmt" func main() { fmt.Println("Hello World") }
程序基本語法
- 所有go源碼以.go結尾;
- 注釋不會被編譯,單行注釋是以 // 開頭,多行注釋以 /* 開頭,以 */ 結尾;
- 標識符以字母或下划線開頭,大小寫敏感,_ 是特殊標識符,用來忽略結果;
- 保留關鍵字:
break | default | func | interface | select |
case | defer | go | map | struct |
chan | else | goto | package | switch |
const | fallthrough | if | range | type |
continue | for | import | return | var |
append | bool | byte | cap | close | complex | complex64 | complex128 | uint16 |
copy | false | float32 | float64 | imag | int | int8 | int16 | uint32 |
int32 | int64 | iota | len | make | new | nil | panic | uint64 |
println | real | recover | string | true | uint | uint8 | uintptr |
程序基本結構
1. 任何一個代碼文件隸屬於一個包
2. golang可執行程序,package main,並且有且只有一個main入口函數
3. 包中函數調用:
- 同一個包中函數,直接調用
- 不同包中函數,通過包名+點+函數名進行調用
4. 包訪問控制規則:
- 大寫意味着這個函數/變量是可導出的
- 小寫意味着這個函數/變量是私有的,包外部不能訪問
項目目錄
$ tree project
project
├── bin
│ ├── example1
│ └── goroute_example
├── pkg
├── src
│ └── go_dev
│ └── day1
│ ├── example1
│ │ ├── debug
│ │ └── hello.go
│ └── goroute_example
│ ├── goroute
│ │ └── add.go
│ └── main
│ └── main.go
└── vender
Src 源碼文件
Bin 編譯后二進制文件
vender 第三方
pkg 靜態文件
簡單栗子
$ tree project
project
├── bin
│ └── goroute_example
├── pkg
├── src
│ └── go_dev
│ └── test1
│ └── goroute_example
│ ├── goroute
│ │ └── add.go
│ └── main
│ └── main.go
└── vender
[main.go] package main import ( "fmt" "go_dev/test1/goroute_example/goroute" ) func main() { pipe := make(chan int, 1) go goroute.Add(pipe, 10, 20) sum := <-pipe fmt.Println(sum) }
[add.go] package goroute func Add(pipe chan int, a int, b int) { pipe <- (a + b) }
$ go build -o bin/goroute_example go_dev/test1/goroute_example/main $ bin/goroute_example 30 $