文章目錄
- 1.1 函數的定義
- 1.2 成員函數定義
- 1.3 函數的嵌套
- 2.1 GOPATH
1,函數1.1 函數的定義
Go支援匿名函數和閉包,Go的函數類似Python可以返回多個值。Go也是靜態編譯型的語言。先來看看Go的函數定于格式:
func 函數名(參數表...) [(傳回值...)] { //函數體}
注意:
1,傳回值在參數表後定義,如果只有一個傳回值,那麼傳回值兩邊的括弧是不要的,如果沒有傳回值那麼傳回值這一項可以省略。
2,函數體的開始大括弧必須在行尾,這是強制的,類似的if, switch中的也是如此。
3,如果函數名大寫字母開頭,那麼就是對外可見的(exported, public)。如果是小寫字母那麼就是包內(package level)私人的。
1.2 成員函數定義
func (t *type) 函數名(參數表...) [(傳回值...)] { //函數體}
這樣就可以為type定義一個成員函數了。
1.3 函數的嵌套
你可以在一個函數體內定義匿名函數甚至你可以定義匿名函數,然後用變數去引用這個匿名函數。但是你不可以在函數體內嵌套定義一個具名函數。
func main() {func () {fmt.Println("anonymous func is ok")}()var foo = func () {fmt.Println("using a variable to refer anonymous func is ok")}foo()func notAllow() {fmt.Println("you can not define named func")}}
匿名函數在這裡有值(value type)的語義。你可以像對待一個值那樣去對待匿名函數(當參數傳遞,作為函數傳回值)。但是具名函數不享有這種優待。相對於JavaScript或Lisp這樣的語言,他缺少了“可以在任意位置定義函數”的能力。在Go中,匿名函數有這種能力。
2,構建系統(build)2.1 GOPATH
當前的項目目錄要添加到GOPATH中,你可以用$go env來檢查你當你的環境變數,包括GOPATH。
如果,你想列出目前的目錄下所有的包(packages),可以使用
$go list ./…
當你GOPATH設定過了以後,你所有以go開頭的命令,都是以GOPATH指定的項目目錄為起始目錄的。
比如:
$go test algorithm/bubblesort #目錄為[項目ROOT]src/algorithm/bubblesort,go test是找src目錄下的還有test的包
3,三個點(…)
對於定義不定參數數量的函數需要三個點…:
func(a, b int, z float64, opt ...interface{})
最後一個為任意類型的的不定參數,用…來標明。
還有個時常用到…的地方是對數組切片添加元素,當添加的元素是數組或數組切片類型的,append(arr, …T)需要將元素“打散”以當做不定參數來傳遞,這時也要用到…:
s2 := append(s1, 3, 5, 7) //一個一個傳遞s3 := append(s2, s0...) //將數組“打散傳遞”
4,goroutine
goroutine是Go語言在語言層級對並發的支援。並發執行體的粒度從系統到輕量級線程分別有:進程,線程,輕量級線程。goroutine應該算是輕量級線程,在我的電腦上(Win7, Intel i7)可以在3s內建立大約300,000個goroutine。
對於並發來說最大的問題是同步和通訊,在Go語言中同步和通訊是通過語言內建的channel來近乎完美解決的。channel不僅僅是goroutine通訊的方式,也通過自動阻塞這種方式達到了同步的目的。channel可以作為函數的參數傳來傳去,channel這個參數在使用上像一個參考型別。他可以跨“函數”傳遞訊息。然而實際上他是實值型別,channel是函數通訊的邊界,你不能通過channel來執行還有副作用的賦值操作——當然,除了你通過傳遞一個指標硬要這麼做。
package main import "fmt"func intGenerator(ch chan int) {for i := 0; i < 10; i++ {ch <- i //pass the i to the channel}close(ch) //close the channel}func main() {var ch chan int = make(chan int)go intGenerator(ch)for {val, ok := <-ch //if channel closed, the ok will be falseif ok {fmt.Println(val) } else {return}}}