Go入門筆記
《Go程式設計語言》作者Kerninghan教授與谷歌GO開發團隊核心成員聯合編寫,Go語言程式設計聖經。本筆記是學習翻閱此書中文翻譯版,整理而成。 非常感謝李道兵、 高博等辛苦的翻譯。
Go IDE-Golang 使用入門參考如下。
https://www.2cto.com/kf/201704/632395.html
Go語言簡介
【1】Go語言是編譯型語言。Go 的工具鏈將程式的原始檔轉變成機器相關的二進位制指令。Go程式碼是使用包來組織的,包類似於其他語言的模組。一個包由一個或者多個go檔案組成,放在同一個資料夾中,資料夾的名字描述了包的作用。每一個原始檔的開始都使用package宣告,指明瞭這個檔案屬於哪個包。
【2】import 必須在package聲明後面,import匯入聲明後面是組成程式的函式、變數、常量、型別(func、var、const、type)開頭宣告。大部分情況下宣告的順序是沒有關係的。
【3】Go不需要在語句或者聲明後面使用分號結尾,除非有多個語句或者宣告出現在同一行。Go程式碼格式化要求非常嚴格。
【4】Go不允許存在無用的變數或者無用的包匯入,不然會出現編譯錯誤。如果有些變數返回必須需要變數佔位,可以使用空識別符號”_”。空識別符號可以用在任何語法需要變數名但是程式邏輯不需要的地方,例如丟掉每次迭代產生的無用的索引。
【5】“:=”是Go語言中特有的短變數宣告和初始化,更加簡潔,但是通常在一個函式的內部使用,不適合包級別的變數。
// = 使用必須使用先var宣告例如:
var a
a=100
//或
var b = 100
//或
var c int = 100
// := 是宣告並賦值,並且系統自動推斷型別,不需要var關鍵字
d := 100
程序 執行緒 協程
程序:獨立的棧空間,獨立的堆空間,程序之間排程由os完成。
執行緒:獨立的棧空間,共享堆空間,核心執行緒之間排程由os完成。
協程:獨立的棧空間,共享堆空間,排程由使用者自己控制,本質上有點類似於使用者級執行緒,這些使用者級執行緒的排程也是自己實現的。
goroutine-channel-select
參考連結:http://blog.csdn.net/qwertyupoiuytr/article/details/55101258
goroutine:原生支援語言級併發,這個併發的最小邏輯單元就是goroutine。goroutine就是Go語言提供的一種使用者態執行緒,這種使用者態執行緒是跑在核心級執行緒之上的,goroutine在執行時的排程是由Go語言提供的排程器來進行的,建立一個goroutine使用關鍵字go,go建立的goroutine不會阻塞主執行緒:
go func_name()
channel:Channel是Go中的一個核心型別,可以把它看成一個管道,通過它可以傳送或者接收資料進行通訊(communication)。配合goroutine,形成了一種既簡單又強大的請求處理模型。
channel的基本操作:
var c chan int //宣告一個int型別的channel,注意,該語句僅宣告,不初始化channel
c := make(chan type_name) //建立一個無緩衝的type_name型的channel,無緩衝的channel當放入1個元素後,後續的輸入便會阻塞
c := make(chan type_name, 100) //建立一個緩衝區大小為100的type_name型的channel
c <- x //將x傳送到channel c中,如果channel緩衝區滿,則阻塞當前goroutine
<- c //從channel c中接收一個值,如果緩衝區為空,則阻塞
x = <- c //從channel c中接收一個值並存到x中,如果緩衝區為空,則阻塞
x, ok = <- c //從channel c中接收一個值,如果channel關閉了,那麼ok為false(在沒有defaultselect語句的前提下),在channel未關閉且為空的情況下,仍然阻塞
close(c) //關閉channel c
for term := range c {} //等待並取出channelc中的值,直到channel關閉,會阻塞
單向channel:
var ch1 chan<- float64 //只能向裡面寫入float64的資料,不能讀取
var ch2 <-chan int //只能讀取int型資料
select:select用於在多個channel上同時進行偵聽並收發訊息,當任何一個case滿足條件時即執行,如果沒有可執行的case則會執行default的case,如果沒有指定defaultcase,則會阻塞程式,select的語法:
func TestChannel(){
// For our example we'll select across two channels.
c1 := make(chan string)
c2 := make(chan string)
// Each channel will receive a value after some amount
// of time, to simulate e.g. blocking RPC operations
// executing in concurrent goroutines.
go func() {
time.Sleep(time.Second * 1)
c1 <- "one"
}()
go func() {
time.Sleep(time.Second * 2)
c2 <- "two"
}()
// We'll use `select` to await both of these values
// simultaneously, printing each one as it arrives.
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
Go Web簡單例子
package server
import (
"net/http"
"fmt"
"log"
"ch01/lissajous"
)
func Server1() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe("localhost:8000", nil))
}
func handler(w http.ResponseWriter,r *http.Request) {
fmt.Fprintf(w,"URL.PATH = %q\n",r.URL.Path)
lissajous.Lissajous(w)
}