PHP->GO 基礎-函式

Pon發表於2019-12-24
//go語言以包作為管理單位
//每個檔案必須先宣告包
//程式必須有一個main(包)重要
package main

import "fmt"

//入口函式
func main() { //左括號必須和函式名同行
    //呼叫函式,大部分都需要匯入包
    //go語言語句結束沒有分號
    fmt.Println("hello word")
}

無參無返回值函式

package main

import "fmt"
//無參無返回值函式的定義
func MyFunc(){
    a := 666
    fmt.Println("a = ",a)
}

func main() {
    MyFunc() //呼叫函式
}

有參無返回值函式

package main
`
import "fmt"
//有參無返回值函式的定義
//MyFunc2(a int, b string ,c bool) //多個引數
//MyFunc2(a,b,c,d int ) //多個同一型別的引數
//MyFunc2(a,b, int ,c string) //不建議使用此方式定義多個引數
func MyFunc(a int){
    fmt.Println("a = ",a)
}

func main() {
    MyFunc(666) //呼叫函式
}

不定引數型別的函式

package main

import "fmt"

//...int 這樣的的型別 ...type 不定引數型別
//注意:不定引數,一定只能放在形參的最後一個引數
//func MyFunc(a int,arge ...int) { 傳遞引數可以是1個或者多個
func MyFunc(arge ...int) { //傳遞引數可以是0個或者多個
    for i := 0; i < len(arge); i++ {
        fmt.Println("value = ", arge[i])
    }

    for i, data := range arge {
        fmt.Println("value = ", i, data)
    }

}

func main() {
    MyFunc(1, 2, 23) //呼叫函式
}

只有一個返回值函式

package main

import "fmt"

//無參 有一個返回值
//有返回值得函式需要通過return 中斷函式,通過return 返回
func MyFunc01() int {
    return 666
}

//給返回值起一個變數名。go推薦寫法
func MyFunc02() (result int) {
    return 666
}

func MyFunc03() (result int) {
    result = 666
    return result
}

func main() {
    var a int
    //呼叫函式
    a = MyFunc01()
    fmt.Println("a =", a)
    b := MyFunc02()
    fmt.Println("b =", b)
    c := MyFunc03()
    fmt.Println("c =", c)
}

有多個返回值函式

package main

import "fmt"

//多個返回值
func MyFunc01() (int, int, int) {
    return 666, 222, 777
}

//官方推薦寫法
//func MyFunc02() (a,b,c int){
func MyFunc02() (a int, b int, c int) {
    a, b, c = 1, 2, 3
    return
}

func main() {
    a, b, c := MyFunc01()
    fmt.Printf("a= %d,b=%d,c=%d\n", a, b, c)
}

函式的使用案例

package main

import "fmt"

//定義函式
func MaxAndMin(a, b int) (max, min int) {
    if a > b {
        max = a
        min = b
    } else {
        max = b
        min = a
    }
    return //有返回值的函式,必須通過 return 返回
}

func main() {
    max, min := MaxAndMin(25, 36)
    fmt.Printf("max = %d,min = %d", max, min)
    a, _ := MaxAndMin(36, 99) //只取一個值
    fmt.Printf("max = %d", a)
}

函式型別

package main

import "fmt"

//定義函式
func Test(a, b int) (sum int) {
    sum = a + b
    return
}

//函式也是一種資料了下,通過type給函式型別起名
//FuncType 它是一個函式型別
type FuncType func(int, int) int //沒有函式名字,沒有{}

func main() {
    //傳統呼叫方式
    sum := Test(10, 20)
    fmt.Println("result = ", sum)
    // 宣告一個函式型別的變數,變數名叫fTest
    var fTest FuncType
    fTest = Test
    sum = fTest(30, 40) //等價於 Test(10,20)
    fmt.Println("result = ", sum)
}

回撥函式

package main

import "fmt"

func Add(a, b int) (result int) {
    result = a + b
    return
}

func Sub(a, b int) (result int) {
    result = a - b
    return
}

//回撥函式,函式有一個引數是函式型別,這個函式就是回撥函式
//計算器,可以進行四則運算
//多型,多種形態,呼叫同一個介面,可以實現不同的表現
//定義函式
func Calc(a, b int, Ftest FuncType) (result int) {
    result = Ftest(a, b)
    return
}

//函式也是一種資料了下,通過type給函式型別起名
//FuncType 它是一個函式型別
type FuncType func(int, int) int //沒有函式名字,沒有{}

func main() {
    //傳統呼叫方式
    result := Calc(10, 20, Add)
    fmt.Println("result = ", result)

    result = Calc(10, 20, Sub)
    fmt.Println("result = ", result)
}

閉包捕獲外部變數特點

package main

import "fmt"

func main() {

    a := 10
    str := "mian"
    func() {
        //閉包以引用方式捕獲外部變數
        a = 666
        str = "go"
        fmt.Printf("a = %d ,str = %s\n", a, str)
    }() //最後的() 代表直接呼叫
    fmt.Printf("a = %d ,str = %s", a, str) //a = 666 ,str = go

}

閉包的特點

package main

import "fmt"

//函式的返回值是一個匿名函式,返回一個函式型別
func test02() func() int {
    var x int
    return func() int {
        x++
        return x * x
    }
}

func main() {
//返回值為一個匿名函式,返回一個函式型別,通過f來呼叫閉包函式
//他不關心這些捕獲了的變數和常量是否已經超出了作用域
//所以只有閉包還在使用它,這些變數就還會存在
    f := test02()
    fmt.Println(f())
    fmt.Println(f())
    fmt.Println(f())
    fmt.Println(f())
    fmt.Println(f())
}

defer的使用

package main

import "fmt"

func main() {
    //defer 延遲呼叫,main 函式結束前呼叫
    //  有多個defer  語句  他們會以  LIFO  (現進後出)的順序執行,哪怕函式或某個領域出現錯誤,這些呼叫依舊會被執行
    defer fmt.Println("bbbb") //最後輸出
    fmt.Println("aaaaa")

}

defer同匿名函式的使用

package main

import "fmt"

func main() {
    a := 10
    b := 20
    defer func(a, b int) {
        fmt.Printf("a = %d,b = %d\n", a, b) //後執行 輸出111,222
    }(a, b) //傳參時  defer 是先傳當前引數(a = 10,b=20),最後執行  所以輸出 a = 10 b =20
    a = 111
    b = 222
    fmt.Printf("a = %d,b = %d\n", a, b) //先執行 輸出111,222

}

func main01() {
    a := 10
    b := 20
    defer func() {
        fmt.Printf("a = %d,b = %d\n", a, b) //後執行 輸出111,222
    }()
    a = 111
    b = 222
    fmt.Printf("a = %d,b = %d\n", a, b) //先執行 輸出111,222

}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章