第02天(函数、工程管理)_03

11_函数类型.go

package main //必须

import "fmt"

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

func Minus(a, b int) int {
    return a - b
}

//函数也是一种数据类型, 通过type给一个函数类型起名
//FuncType它是一个函数类型
type FuncType func(int, int) int //没有函数名字,没有{}

func main() {
    var result int
    result = Add(1, 1) //传统调用方式
    fmt.Println("result = ", result)

    //声明一个函数类型的变量,变量名叫fTest
    var fTest FuncType
    fTest = Add            //是变量就可以赋值
    result = fTest(10, 20) //等价于Add(10, 20)
    fmt.Println("result2 = ", result)

    fTest = Minus
    result = fTest(10, 5) //等价于Minus(10, 5)
    fmt.Println("result3 = ", result)
}

12_回调函数.go

package main //必须

import "fmt"

type FuncType func(int, int) int

//实现加法
func Add(a, b int) int {
    return a + b
}

func Minus(a, b int) int {
    return a - b
}

func Mul(a, b int) int {
    return a * b
}

//回调函数,函数有一个参数是函数类型,这个函数就是回调函数
//计算器,可以进行四则运算
//多态,多种形态,调用同一个接口,不同的表现,可以实现不同表现,加减乘除
//现有想法,后面再实现功能
func Calc(a, b int, fTest FuncType) (result int) {
    fmt.Println("Calc")
    result = fTest(a, b) //这个函数还没有实现
    //result = Add(a, b) //Add()必须先定义后,才能调用
    return
}

func main() {
    a := Calc(1, 1, Mul)
    fmt.Println("a = ", a)
}

13_匿名函数和闭包.go

package main //必须

import "fmt"

func main() {
    a := 10
    str := "mike"

    //匿名函数,没有函数名字, 函数定义,还没有调用
    f1 := func() { //:= 自动推导类型
        fmt.Println("a = ", a)
        fmt.Println("str = ", str)
    }

    f1()

    //给一个函数类型起别名
    type FuncType func() //函数没有参数,没有返回值
    //声明变量
    var f2 FuncType
    f2 = f1
    f2()

    //定义匿名函数,同时调用
    func() {
        fmt.Printf("a = %d, str = %s\n", a, str)
    }() //后面的()代表调用此匿名函数

    //带参数的匿名函数
    f3 := func(i, j int) {
        fmt.Printf("i = %d, j = %d\n", i, j)
    }
    f3(1, 2)

    //定义匿名函数,同时调用
    func(i, j int) {
        fmt.Printf("i = %d, j = %d\n", i, j)
    }(10, 20)

    //匿名函数,有参有返回值
    x, y := func(i, j int) (max, min int) {
        if i > j {
            max = i
            min = j
        } else {
            max = j
            min = i
        }

        return
    }(10, 20)

    fmt.Printf("x = %d, y = %d\n", x, y)

}

14_闭包捕获外部变量的特点.go

package main //必须

import "fmt"

func main() {
    a := 10
    str := "mike"

    func() {
        //闭包以引用方式捕获外部变量
        a = 666
        str = "go"
        fmt.Printf("内部:a = %d, str = %s\n", a, str)
    }() //()代表直接调用

    fmt.Printf("外部:a = %d, str = %s\n", a, str)
}

15_闭包的特点.go

package main //必须

import "fmt"

//函数的返回值是一个匿名函数,返回一个函数类型
func test02() func() int {
    var x int //没有初始化,值为0

    return func() int {
        x++
        return x * x
    }
}

func main() {

    //返回值为一个匿名函数,返回一个函数类型,通过f来调用返回的匿名函数,f来调用闭包函数
    //它不关心这些捕获了的变量和常量是否已经超出了作用域
    //所以只有闭包还在使用它,这些变量就还会存在。
    f := test02()
    fmt.Println(f()) //1
    fmt.Println(f()) //4
    fmt.Println(f()) //9
    fmt.Println(f()) //16
    fmt.Println(f()) //25

}

func test01() int {
    //函数被调用时,x才分配空间,才初始化为0
    var x int //没有初始化,值为0
    x++
    return x * x //函数调用完毕,x自动释放
}

func main01() {
    fmt.Println(test01())
    fmt.Println(test01())
    fmt.Println(test01())
    fmt.Println(test01())
}

16_defer的使用.go

package main //必须

import "fmt"

func main() {
    //defer延迟调用,main函数结束前调用
    defer fmt.Println("bbbbbbbbbbbbb")

    fmt.Println("aaaaaaaaaaaaaaa")
}

17_多个defer的执行顺序.go

package main //必须

import "fmt"

func test(x int) {
    result := 100 / x

    fmt.Println("result = ", result)
}

func main() {

    defer fmt.Println("aaaaaaaaaaaaaa")

    defer fmt.Println("bbbbbbbbbbbbbb")

    //调用一个函数,导致内存出问题
    defer test(0)

    defer fmt.Println("ccccccccccccccc")
}

你可能感兴趣的:(第02天(函数、工程管理)_03)