這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1,if條件陳述式注意事項:條件陳述式不需要使用括弧將條件包含起來 () ; 無論語句體內有幾條語句,花括弧 {} 都是必須存在的; 左花括弧 { 必須與 if 或者 else 處於同一行; 在 if 之後,條件陳述式之前,可以添加變數初始化語句,使用 ; 間隔;
2,slice可直接使用append對其進行添加元素如append(slice,slice對應元素),也可直接在slice中添加slice,不過此時寫法為append(slice1,slice2…),其中slice2後有…表示將slice2打散成元素後再添加到slice1中
3,break可以後面加標籤,表示跳出對應標籤的迴圈。如break Look表示跳出外層迴圈。
Loop: for i := 0; i < 5; i++ { for j := 0; j < 5; j++ { if j >= 4 { break Loop } } }
4,go中可使用不定參數,其使用方法如下:“…type”表示具有不定個type類型的參數,不定參數實質上是一個slice類型,故可以使用range對其參數進行取值。如下例子。
func myfunc(args ...int) { for _, arg := range args { fmt.Println(arg) }}
5.go語言中沒有建構函式的概念,對象的構建通常交給一個全域構建函數來構建,通常以NewXXX來命名,表示建構函式。如
func NewRect(x, y, width, height float64) *Rect { return &Rect{x, y, width, height}}
6.go語言中對於堆和棧的記憶體配置沒有嚴格區分,在go中返回一個局部變數的地址是絕對沒有問題的,變數關聯的儲存在函數返回後依然存在.(註:尤其對由C/C++轉過來的程式員,開始肯定不是很適應,但是go這種記憶體配置方式解放了程式員,使得程式員能夠專註做事情,而不用花費太多的時間在堆和棧的記憶體配置上).更直接的說,在go語言中,如果一個局部變數在函數返回後仍然被使用,那麼這個變數會在堆heap,而不是棧stack中進行記憶體配置.詳情參考How do I know whether a variable is allocated on the heap or the stack?
7. golang允許多個傳回值,並且傳回值有兩種形式,一種只是指定類型,還有一種指定傳回值名稱.如下所示:
func SumAndProduct(a, b int) (int, int) { return a+b, a*b} func SumAndProduct(a, b int) (add int, Multiplied int) { add = a + b; Multiplied = a * b; return}
當定義函數時指定返回參數變數時,可以直接返回而不用帶變數名。注意:如果命令的返回參數跟函數代碼塊中的變數同名,他會被隱藏,此時需顯示return返回結果;還有就是顯式return會先修改命名傳回值,然後再執行defer延遲語句。由於會出現函數中臨時變數名和指定傳回值名字衝突的情況,所以建議使用不指定傳回值名稱的形式.
8.參數之變參:golang支援變參,變數中所有參數的類別必須是同一種,且必須是最後一個形參。函數內擷取變參為一個slice。函式宣告為:func FuncName(args ...int) { } args ...int 告訴go這個函數接受變參參數。 使用如sum(x[2:6]...)
9. defer 與return執行順序
當函數執行到最後時,先執行defer語句,然後才執行return語句.所以可以利用這個來進行資源安全關閉,解加鎖,記錄執行情況等。defer是採用先進後出的模式的,這種情形與棧的情況一致。注意:定義的defer延遲操作,如有提供參數會發生值的拷貝,儘管這些函數在退出時才執行,但所使用的參數是在定義時就進行拷貝,拷貝的原則和變數的賦值原則一個,slice,map,channel是指標拷貝.如下例子:
<span style="color:#000000;">package mainimport ("fmt")func main() {x := 1defer func(a int) { //直接將x=1賦值給a,雖然他在後面才執行.fmt.Println("a=", a)}(x)defer func() {fmt.Println("x=", x) //經過x++後,x值變為2}()x++}運行結果: x= 2 a= 1</span>