天天看點

Go語言學習筆記(一)Let's 幹吧簡介語言特性編譯器安裝go 标準指令Hello World 程式基本文法程式基本結構簡單栗子

加 Golang學習 QQ群共同學習進步成家立業工作 ^-^ 群号:96933959

簡介

Go語言學習筆記(一)Let's 幹吧簡介語言特性編譯器安裝go 标準指令Hello World 程式基本文法程式基本結構簡單栗子

    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. 垃圾回收

  1. 記憶體自動回收,再也不需要開發人員管理記憶體 
  2. 隻需要new配置設定記憶體,不需要釋放

2. 天然并發

  1. 從語言層面支援并發,非常簡單
  2. Goroutine,輕量級線程,建立成千上萬個Goroutine成為可能
  3. 基于CSP(Communicating Sequential Process)模型實作

3. channel

  1. 管道,類似unix/linux中的pipe
  2. 多個Goroutine之間通過channel進行通信
  3. 支援任何類型
  4. 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),允許将源碼編譯為可在目标系統、架構上執行的二進制檔案。

安裝

下載下傳位址:

https://golang.org/dl/ https://golang.org/dl/

設定環境變量:

  1. export GOROOT=$PATH:/path/to/go/
  2. export PATH=$PATH:$GOROOT/bin/
  3. export GOPATH=/home/user/project/go

終端測試:

  1. go version
  2. go env
  3. Gofmt -w *.go

IDE安裝可參考:

  1. http://www.cnblogs.com/zsy/archive/2016/02/28/5223957.html

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語言的環境資訊。

名稱 說明
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")
}      

程式基本文法

  1. 所有go源碼以.go結尾;
  2. 注釋不會被編譯,單行注釋是以 // 開頭,多行注釋以 /* 開頭,以 */ 結尾;
  3. 辨別符以字母或下劃線開頭,大小寫敏感,_ 是特殊辨別符,用來忽略結果;
  4. 保留關鍵字:
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
print println real recover string true uint uint8 uintptr

程式基本結構

1. 任何一個代碼檔案隸屬于一個包

2. golang可執行程式,package main,并且有且隻有一個main入口函數

3. 包中函數調用:

  1. 同一個包中函數,直接調用
  2. 不同包中函數,通過包名+點+函數名進行調用

4. 包通路控制規則:

  1. 大寫意味着這個函數/變量是可導出的
  2. 小寫意味着這個函數/變量是私有的,包外部不能通路

項目目錄

$ 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
$