初識golang之函數

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。 聲明: func funcName(input1 type1, intput2 type2) (output1 type1, output2 type2) {     ………………
    //可以有多個傳回值
    return val1, val2
} 說明:golang中通過func來聲明一個函數,函數可以有一個或者多個參數,每個參數後面帶類型,通過,分隔;函數可以返回多個值,返回的個數要於聲明時定義的返回個數相同,聲明時可以不寫返回的變數名,而直接使用類型(如果只有一個傳回值且不聲明傳回值變數,那麼可以省略傳回值的括弧,如果沒有傳回值,那麼就直接省略最後的返回資訊定義) 例: 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延遲語句。
參數之變參: golang支援變參,變數中所有參數的類別必須是同一種,且必須是最後一個形參。函數內擷取變參為一個slice。函式宣告為:func FuncName(args ...int) { } args ...int 告訴go這個函數接受變參參數。 使用如sum(x[2:6]...)
參數的使用: 函數的參數都是進行拷貝賦值的,只是分為copy值和copy指標,傳遞指標使用“&變數名”,在函式宣告中使用“變數名 *類型”,如: func Add(num *int) int {     *num = *num + 100
    return *num
} 使用,nmber := 100 Add(&number) fmt.Println(number) go語言中,string,slice,map這三種類型實現的機制類似指標,所以可以直接傳遞,而不用取地址後傳遞指標。若函數需要改變slice長度,則仍需去地址傳遞指標。
匿名函數和閉包:

閉包和匿名函數經常一起使用,可以使用閉包來訪問函數中的局部變數(被訪問操作的變數為指標指向關係,操作的是同一個局部變數)如:

func closure(x int) (func(), func(int)) {    fmt.Printf("初始值x為:%d,記憶體位址:%p\n", x, &x)    f1 := func() {        x = x + 5        fmt.Printf("x+5:%d,記憶體位址:%p\n", x, &x)    }    f2 := func(y int) {        x = x + y        fmt.Printf("x+%d:%d,記憶體位址:%p\n", y, x, &x)    }    return f1, f2}func main() {    func1, func2 := closure(10)    func1()    func2(10)    func2(20)}
輸出結果為:
初始值x為:10,記憶體位址:0xc080000038
x+5:15,記憶體位址:0xc080000038
x+10:25,記憶體位址:0xc080000038
x+20:45,記憶體位址:0xc080000038

延遲語句defer:
golang中,有種語句defer語句,在函數執行到最後時,這些defer語句才會按照定義的逆序執行,等這些defer語句都執行完後,函數再返回。所有可以利用這個來進行資源安全關閉,解加鎖,記錄執行情況等。defer是採用先進後出的模式的,如棧。注意:定義的延遲操作,如有提供參數會發生值的拷貝,儘管這些函數在退出時才執行,但所使用的參數是在定義時的拷貝,拷貝的原則和變數的賦值原則一個,slice,map,channel是指標拷貝。

函數作為值、類型: 在golang中函數也是一種變數,可以使用type來定義它,它的類型就是所有擁有相同的參數,相同的傳回值的一種類型 type TypeName func(input1 type1, input2 type2) (output1 type1, output2 type2) 函數作為類型就可以把這個類型的函數當作值來傳遞,如物件導向中的組合方法,如: //聲明一個函數類型 type handlerNum func(int) int
func Add(num int) int {     sum := 0
    for i := 1; i <= num; i++ {
        sum += i
    }
    return sum
}
func  Product(num int) int {     return (1 + 100) * 100 / 2
}
func Gauss (num int, h handlerNum) {     return h(num)
}
Gauss(100, Add) 和 Gauss(100, Product)這兩個函數得到的結果都是一樣的。
Panic和Recover: golang中沒有異常機制,它不能拋出異常,而是使用了panic和recover機制,panic它會中斷原有的控制流程程,並進入一個恐慌流程中,當函數調用panic,原有函數的執行會被中斷,但原有函數中的defer函數會正常的執行,然後函數返回到調用它的地方 。在調用的地方,函數的行為就像調用了panic,這一過程繼續向上,直到發生panic的gorutine中所有調用的函數返回,此時程式退出。恐慌可以直接調用panic產生,也可以有執行階段錯誤產生。recover可以讓進入恐慌流程中的goroutine恢複過來,recover僅在defer延遲函數內部中有效,在正常的執行過程中,調用recover會返回nil,並且沒有其他任務效果,如果當前的goroutine陷入恐慌,調用recover可以捕獲panic的輸入值,並恢複正常的程式執行。
main函數和init函數: golang中的兩個保留函數,init函數能夠應用於所有的package,main函數只能應用於main包中,兩個函數在定義時不能有任何的參數和傳回值,一個package可以有多個init函數,但為了可讀性強烈建議使用者在一個package中每個檔案唯寫一個init函數,而main函數有且一個存在main包中。 程式初始化和執行都起始於main包,如果main包還匯入其他的包,那麼會在編譯時間將他們依次匯入,當一個包被多個包同時匯入,那麼它只會匯入一次,當匯入的包還引入了其他的包,那麼還會先將其他包匯入進來,然後再對這些包的包級常量和變數進行初始化,接著執行init函數,依次類推,等所有的被匯入的包都載入完畢並初始化完畢後,就會開始對main包的包級常量和變數進行初始化,然後執行main包中的init函數,最後執行main函數。const->var->init->main的過程。
內建函數: close:關閉channel。 len:擷取string,array,slice的長度,map key的數量和buffer channel可用資料數量。 cap:擷取array長度、slice容量,以及buffer channel的最大緩衝容量。 new:對指定類型分配初始化過的記憶體空間(零值填充),並返回指標。 make:僅用於slice、map、channel指標賦實值型別,除了初始化記憶體,還負責設定相關屬性。 append:向slice尾部追加一個或多個元素。 copy:在不同的slice間複製資料,並返回複製的個數,如:copy(s1, s2[2:7]) panic/recover:錯誤處理 complex/real/imag:複數處理。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.