Go語言規格說明書 之 Go語句(Go statements)

go version go1.11 windows/amd64

 

本文爲閱讀Go語言中文官網的規則說明書(https://golang.google.cn/ref/spec)而做的筆記,介紹Go語言的 Go語句(Go statements)

 

Go語句 用於將一個 函數調用 作爲一個 獨立的併發線程(an independent concurrent thread of control) 或者 叫做 Go例程(goroutine) 來執行——新建一個Go例程、立即執行,這個 新的Go例程 和 之前的程序 在同一個地址空間。

疑問,Go程序運行後——從main()函數進入——是運行一個 進程 吧?這個進程有 主線程 吧?Go例程 就是 建立了一個新的線程,和 主線程 併發 運行——在僅有一個CPU時交替使用CPU資源,在有多個CPU時,是否在不同的CPU上運行?後者是並行吧?那麼,這裏的併發,是否包含了並行?Go例程裏面 還可以 啓動新的Go例程嗎?如果可以,允許的最大層級是怎樣的?對於Go例程和創建它的程序共享地址空間這個問題,還不是很清楚,有什麼用呢?Go例程可以使用原程序中的 變量、常量 等——讀和寫?

GoStmt = "go" Expression .

上面是Go語句的 語法,其中的 表達式(Expression)必須是 函數 或 方法調用,並且不能用圓括號括起來(是指Expression不能被括起來吧?把go Expression用一起括起來應該是可以的)。

雖然Expression可以是 法術 或 方法調用,但是,對於內建函數的使用是有限制的(Expression statements),下面這些 內建函數 不能出現在 語句上下文——包括Go語句 中:

append cap complex imag len make new real
unsafe.Alignof unsafe.Offsetof unsafe.Sizeof

說明,append不可以,但copy可以;複數的三個內建函數都不可以;獲取長度、容量的函數不可以;new、make不可以;還有unsafe包中的幾個函數——暫不清楚它們的用處。

 

在Go例程中,函數的值和參數 和 正常調用 一樣被求值,但和正常調用不同的是,程序的執行 不會 等到被調用的函數完成,相反,程序開始在一個新的Go例程中獨立地執行。

在函數 終止 時,它的Go例程也會終止。如果函數有返回值,這些返回值會在函數完成時被 丟棄。

解讀,根據上面的信息,Go例程 有什麼用途呢?可以用在什麼地方呢?耗時操作?Web服務器 的一個用戶請求處理程序?一個程序 可以新建多少Go例程呢?和計算機的資源多少有關係?新建的Go例程只能在本機運行嗎?可以指派到其它計算機上執行——實現分佈式執行?一臺電腦的程序 被 放到 另一臺電腦執行,感覺像是 控制了另一臺電腦?Go語言本身是否支持這樣的操作?不然的話,一定會有其它軟件實現方式的。畢竟那麼多病毒程序都已經實現了。

 

官文示例:

go Server()
go func(ch chan<- bool) { for { sleep(10); ch <- true }} (c) // 注意這裏的 (c),這是函數調用 的 括號 及 參數

 

上面的官文示例就太簡單了,下面給出一個複雜一些的——來自網絡:

通過 篩選法 尋找素數——這個程序俺大致看懂了,晚點會徹底看懂它。

原文鏈接不知道在哪裏了,網上可以搜索到類似的鏈接,比如,http://www.yankay.com/go-clear-concurreny/ (Go-簡潔的併發),

package main 

import (
	"fmt"
)

// Send the sequence 2, 3, 4, ... to channel 'ch'
func generate(ch chan<- int) {
	for i := 2; ; i++ {
		ch <- i // Send 'i' to channel 'ch'
	}
}

// Copy the values from channel 'src' to channel 'dst',
// removing those divisible by 'prime'.
func filter(src <-chan int, dst chan<- int, prime int) {
	for i := range src { // Loop over values received from 'src'
		if i%prime != 0 {
			dst <- i // Send 'i' to channel 'dst'
		}
	}
}

// The prime sieve: Daisy-chain filter processes together.
func sieve() {
	ch := make(chan int) // Create a new channel.
	go generate(ch) // Start generate() as a subprocess.
	for {
		prime := <-ch
		fmt.Print(prime, "\n")
		ch1 := make(chan int)
		go filter(ch, ch1, prime)
		ch = ch1
	}
}

func main() {
	sieve()
}

 

參考鏈接

1.Go語言併發的設計模式和應用場景

2.Go-簡潔的併發

 

後記

好了,很清楚Go例程是什麼了,但是還有一些疑問需要搞清楚!

另外,Go語言 內置 的併發特性有什麼好處呢?好需要更多實踐來體會纔是!

官文Effective Go中有一節名爲Concurrency,稍候會好好看看,有需要,再補充此文——估計不會的了。

 

學習編程語言,就是爲了 解決問題,要親自寫代碼去解決問題。

比如上面的尋找素數的問題,若是自己來寫,用Go語言來寫,會寫成什麼樣呢?估計是不會用Go例程的!可先行者們知道用Go例程了,看來自己的Go學習之路還有些漫長呢!

只有繼續投入精力了!

還有Go開發者可以使用Go語言開發區塊鏈程序了,感覺好高級啊!

什麼時候自己也可以寫點 高級的程序呢?

從上月末開始學(接觸)Go開發,直到現在都還沒 用Go寫一個Web服務器出來,方式方法&行動力都存在嚴重問題啊!

需反省,改進!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章