[golang note] 函數定義


普通函數定義


       golang函數基本組成:關鍵字func函數名參數列表返回值函數體返回語句

• 語法如下

func 函數名(參數列表) (返回值列表) {
    // 函數體
}

• 示例如下

package main

import "fmt" import "errors" func Add(a int, b int) (ret int, err error) {
    if a < 0 || b < 0 { // 假定只支持兩個非負數字的加法
        err = errors.New("Should be non-negative numbers!")
        return }     return a + b, nil
}

func main() {
    fmt.Println(Add(-1, 1))
    fmt.Println(Add(10, 1))
}

• 注意事項

       ▪ golang函數支持多返回值,返回時沒有被明確賦值的返回值將被設置為默認值

       ▪ golang函數返回值可以命名,但不是強制規則,給返回值命名可以讓讓代碼更清晰,可讀性更強,同時也可以用於文檔。

       ▪ golang函數定義中左花括號的位置被強制規范,如果左花括號放置不規范,golang編譯器報告編譯錯誤:syntax error: unexpected semicolon or newline before {。

       ▪ golang函數定義中如果參數列表中若干個相鄰參數的類型相同,則可以在參數列表中省略前面的變量類型聲明。

func Add(a, b int) (ret int, err error) {
    // 函數體
}

       ▪ golang函數定義中如果返回值列表中若干個相鄰返回值的類型相同,則可以在返回值列表中省略前面的變量類型聲明。

func Add(a, b int) (ret, err int) {
    // 函數體
}

       ▪ golang函數定義中如果返回值只有一個,那么返回值列表可以簡略表示。

func Add(a, b int) int {
    // 函數體
}

固定類型的不定參數函數定義


• 語法如下

func 函數名(args ...Type) (返回值列表) {
    // 函數體
}

       形如args ...Type的用法只能作為函數的參數類型,並且必須是最后一個參數

       形如args ...Type的用法是一個語法糖(syntactic sugar),即對語言功能沒有影響,但可以增加程序的可讀性。

       形如args ...Type的用法從內部實現上說,其本質上是一個數組切片,即[]type,因此可以用for循環來獲得每個傳入的參數。

• 示例如下

package main

import "fmt" func myfunc(prefix string, args ...int) {
    fmt.Print(prefix, " : ")

    for _, arg := range args {
        fmt.Print(arg, " ")
    }

    fmt.Println()
}

func main() {
    myfunc("data1", 1, 2, 3, 4)
    myfunc("data2", 4, 3, 2, 1, 0)
}

• 不定參數函數互相調用

▶ 原樣傳遞

▪ 語法如下

func myfunc1(args ...Type) {
    // 函數體
}

func myfunc2(args ...Type) {
    ...
    myfunc1(args...)
    ...
}

▪ 示例如下

package main

import "fmt" func myfunc1(args ...int) {
    fmt.Println("myfunc1() invoked")

    for _, arg := range args {
        fmt.Print(arg, " ")
    }

    fmt.Println()
}

func myfunc2(args ...int) {
    fmt.Println("myfunc2() invoked")
    myfunc1(args...)
}

func main() {
    myfunc2(1, 2, 3, 4)
}

▶ 片段傳遞

▪ 語法如下

func myfunc1(args ...Type) {
    // 函數體
}

func myfunc2(args ...Type) {
    ...
    myfunc1(args[m:n]...)
    ...
}

▪ 示例如下

package main

import "fmt" func myfunc1(args ...int) {
    fmt.Println("myfunc1() invoked")

    for _, arg := range args {
        fmt.Print(arg, " ")
    }

    fmt.Println()
}

func myfunc2(args ...int) {
    fmt.Println("myfunc2() invoked")
    myfunc1(args[2:3]...)
}

func main() {
    myfunc2(1, 2, 3, 4)
}

任意類型的不定參數函數定義


• 語法如下

func 函數名(args ...interface{}) (返回值列表) {
    // 函數體
}

       形如args ...interface{}的用法只能作為函數的參數類型,並且必須是最后一個參數。

• 示例如下

package main

import "fmt" func MyPrintf(info string, args ...interface{}) {
    fmt.Println(info)
    for _, arg := range args {
        switch arg.(type) {
        case int:
            fmt.Println(arg, "is an int value.")
        case string:
            fmt.Println(arg, "is a string value.")
        case int64:
            fmt.Println(arg, "is an int64 value.")
        default:
            fmt.Println(arg, "is an unknown type.")
        }
    }
}

func main() {
    var v1 int = 1
    var v2 int64 = 234
    var v3 string = "hello"
    var v4 float32 = 1.234

    MyPrintf("MyPrintf", v1, v2, v3, v4)
}

匿名函數與閉包


• 匿名函數

        匿名函數是指不需要定義函數名的一種函數實現方式,函數可以像普通變量一樣被傳遞或使用。

▶ 匿名函數賦值給變量

▪ 語法如下

f := func(參數列表) (返回值列表) {
    // 函數體
}

▪ 示例如下

package main

import "fmt" func main() {
    f := func(x, y int) int {
        return x + y
    }

    fmt.Println("Result =", f(1, 2))
}

▶ 匿名函數直接調用

▪ 語法如下

        匿名函數定義的花括號后直接跟參數列表表示函數調用。

func(參數列表) (返回值列表) {
    // 函數體
} (參數列表)

▪ 示例如下

package main

import "fmt" func main() {
    fmt.Println("Result =",
        func(x, y int) int {
            return x + y
        }(1, 2))
}

• 閉包

▶ 閉包概念

        閉包是可以包含自由變量(未綁定到特定對象)的代碼塊。這些自由變量不在該代碼塊內或任何全局上下文中定義,而是在定義代碼塊的環境中定義。要執行的代碼塊為自由變量提供綁定的計算環境,即作用域。

        自由變量包含在代碼塊中,這些自由變量以及其引用的對象將不被釋放。閉包的實現確保只要閉包還被使用,那么被閉包引用的變量會一直存在。

        golang的匿名函數就是一個閉包,閉包函數可以存儲到變量中作為參數傳遞給其他函數,最重要的是能夠被函數動態創建和返回。

        自由變量的值將被隔離,在閉包外不可修改,只有內部匿名函數才能訪問,而無法通過其他途徑訪問,因此確保了變量的安全性。

▶ 閉包使用

▪ 語法如下

c := func() func(參數類型列表) 返回值類型列表 {
 // 自由變量定義
...
return func(參數列表) 返回值列表 { // 函數定義 } }()

▪ 示例如下

package main

import (
    "fmt"
)

func main() {
    result := 0

    // 閉包定義
    c := func() func(int) int {
        i := 0
        return func(j int) int {
            i += 10
            fmt.Printf("i = %d, j = %d\n", i, j)
            return i + j
        }
    }()

    result = c(10)
    fmt.Printf("i + j= %d\n", result)

    result = c(20)
    fmt.Printf("i + j= %d\n", result)

    result = c(30)
    fmt.Printf("i + j= %d\n", result)
}

main函數


        main函數是golang可執行程序的執行起點。

        main函數不能帶有參數,命令行傳入的參數在os.Args變量中保存。

package main

import (
    "fmt"
    "os"
)

func main() {
    for i, v := range os.Args {
        fmt.Printf("os.Args[%d] = %s\n", i, v)
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM