美文网首页
10 Go匿名函数 && 闭包

10 Go匿名函数 && 闭包

作者: 亨锅锅 | 来源:发表于2018-10-30 13:09 被阅读0次

    1、函数的基本规则

    package main
    
    import "fmt"
    
    func main() {
        /*
        1.C语言是由函数组成的
        2.Go语言也是由函数组成的
        3.C语言函数的格式
        返回值类型 函数名称(形参列表){
            被控制的语句;
        }
        4.Go语言函数的格式
        func 函数名称(形参列表)(返回值列表){
            被控制的语句;
        }
    
        5.C语言函数的类型
        5.1没有返回值没有形参的函数
        5.2有返回值没有形参的函数
        5.3没有返回值有形参的函数
        5.4有返回值有形参的函数
    
        6.Go语言函数的类型和C语言一样
    
        注意点:
        1.在C语言中如果函数的定义写在函数的调用之前必须先声明再调用
        在Go语言中如果函数的定义写在函数的调用之前, 不用声明就可以调用, Go语言没有声明
        2.Go语言中如果函数只有一个返回值, 那么返回值列表的()可以省略
        3.Go语言中如果有返回值, 可以在返回值列表中定义变量, 然后在函数体中直接使用
        4.如果在返回值列表中定义了变量,  那么return后面可以不用写任何内容, 默认就会将返回值列表中定义的变量返回
        5.Go语言中一个函数可以有多个返回值
        6.如果一个函数有多个返回值, 但是我们只想使用其中的一个, 那么可以在接收的时候使用_来忽略, 不需要的那个返回值
        7.因为_在Go语言中有特殊的含义, 所以在定义标识符的时候_不能单独作为标识符
        8.如果返回值列表中有多个返回值, 并且连续的多个返回值的数据类型都一样, 那么只用在最后一个变量后面添加数据类型即可
        9.如果形参列表中有多个形参, 并且连续的多个形参的数据类型都一样, 那么只用在最后一个变量后面添加数据类型即可
         */
        //say()
        //res := getNumber()
        //fmt.Println(res)
    
        //a, b := getValue()
        //fmt.Println("a = ", a, "b = ", b)
        //a, _ := getValue()
        //fmt.Println("a = ", a)
    
        //sum(10, 20)
    
        res := minus(10, 20)
        fmt.Println(res)
    }
    // 1.没有返回值没有形参的函数
    func say(){
        fmt.Println("没有返回值没有形参")
    }
    // 2.有返回值没有形参的函数
    // 2.1只有一个返回值的函数
    //func getNumber()(int){
    //func getNumber()int{
    //  return 888
    //}
    func getNumber() (num int){
        num = 999
        return
    }
    // 2.2有多个返回值的函数
    //func getValue() (int, int){
    //  return 666, 888
    //}
    //func getValue() (num int,value int){
    func getValue() (num ,value int){
        //num = 666
        //value = 888
        //return
        return 666, 888
    }
    //func test()(num int, temp float64, value int){
    //func test()(num , value int, temp float64){
    //
    //}
    
    // 3.没有返回值有形参的函数
    //func sum(a int, b int){
    func sum(a , b int){
        res := a + b
        fmt.Println(res)
    }
    
    // 4.有返回值有形参的函数
    //func minus(a, b int)(res int){
    //  res = a - b
    //  return
    //}
    
    func minus(a int, b int)(int){
        res := a - b
        return res
    }
    

    2、函数的参数

    package main
    
    import "fmt"
    
    func main() {
        /*
        1.在C语言中如果基本数据类型作为函数的参数, 是值传递, 在函数内修改形参不会影响到外界的实参
        2.Go语言和C语言一样/ int float bool
    
        3.如果想在函数内部修改外界传入的实参, 那么必须传入指针
         */
        num := 666
        fmt.Println(num)
        //change1(num)
        change2(&num)
        fmt.Println(num)
    }
    func change1(a int) {
        a = 789
    }
    
    func change2(a *int) {
        *a = 789
    }
    

    3、什么是匿名函数

    package main
    
    import "fmt"
    
    func main() {
        /*
        1.什么是匿名函数?
        普通的函数都是有名字的函数, 而匿名函数就是没有名字的函数
    
        2.匿名函数的应用场景:
        一般情况下某个函数只会被调用一次, 我们就会使用匿名函数
        作为函数的参数, 或者作为函数的返回值
    
        3.注意点:
        3.1匿名函数定义之后, 如果没有立即调用, 编译器会报错
        3.2也可以将一个匿名函数保存到一个变量中
        在C语言中我们知道, 我们可以定义一个指向函数的指针来保存函数的地址, 然后通过指针来调用函数
        在Go语言中函数是一等公民(可以定义变量, 作为形参, 作为返回值), 所以在Go语言中也可以用函数类型来定义变量(相当于C语言中指向函数的指针)
        3.3由于函数是一等公民, 所以以前定义变量所有的格式, 都可以用于定义函数类型的变量
        var 变量名称 函数类型
        var 变量名称 函数类型 = 匿名函数
        var 变量名称  = 匿名函数
        变量名称  := 匿名函数
        var(
            var 变量名称  = 匿名函数
        )
    
        C语言中指向函数的指针
        int test(int a, int b){}
        int (*test)(int, int)
         */
         // test相当于找到函数的定义, 然后调用函数
         test()
    
         // 直接定义一个函数, 然后立即调用这个函数
         //func(){
         // fmt.Println("匿名函数")
         //}()
    
         // 定义一个函数类型的变量, 保存匿名函数, 然后通过函数类型的变量调用匿名函数
         //f := func() {
            // fmt.Println("匿名函数")
         //}
         var f func() = func() {
             fmt.Println("匿名函数")
         }
         //fmt.Printf("%T\n", f)
         f()
    }
    
    func test(){
        fmt.Println("test")
    }
    

    4、匿名函数的应用

    4.1

    package main
    
    import "fmt"
    
    func main() {
        /*
        1.作为其他函数的参数
        2.作为其他函数的返回值
         */
         /*
         res1 := sum(10, 20)
         res2 := minus(10, 20)
         fmt.Println(res1)
         fmt.Println(res2)
         */
    
         // 需求: 定义一个匿名函数, 实现两个数相加
        //fn := func(a, b int) int {
        //  return  a + b
        //}
        //fmt.Printf("%T\n", fn)
    
        //相当于如下:
        //var fn func(int, int) int = func(a, b int) int {
        //  return  a + b
        //}
        //res := fn(10, 20)
        //fmt.Println(res)
    
        //var method func(int, int) int = fn
        //res := method(10, 20)
        //fmt.Println(res)
    
        //匿名函数的赋值 和 变量的使用 类比如下
        //var num int = 6
        //var value int = num
        //fmt.Println(value)
    
        //result := calculate(10, 20, fn)
    
        result := calculate(10, 20, func(a, b int) int {
            return  a + b
        })
        fmt.Println(result)
    }
    func calculate(a, b int, method func(int, int) int) (int) {
        res := method(a, b)
        return res
    }
    
    func sum(a, b int) int {
        return  a + b
    }
    func minus(a, b int) int {
        return  a - b
    }
    

    4.2

    package main
    
    import "fmt"
    
    func main() {
    
        // 1.匿名函数作为函数的参数
        /*
        //var fn func()
        //fn = func() {
        //  fmt.Println("匿名函数")
        //}
        //fmt.Printf("%p\n", fn)
        //test(fn)
    
        test(func() {
            fmt.Println("匿名函数")
        })
        */
        /*
        var fn func()
        fn = test()
        fn()
        */
    
        //2.作为其他函数的返回值
        var fn func(int, int)int
        fn = test()
        res := fn(10, 20)
        fmt.Println(res)
    }
    
    func test()func(int, int)int{
        return func(a int, b int)int {
            return a + b
        }
    }
    
    
    //func test() func() {
    //  return func() {
    //      fmt.Println("匿名函数")
    //  }
    //}
    
    //func test(method func())  {
    //  fmt.Printf("%p\n", method)
    //  method()
    //}
    

    4.3、

    package main
    
    import (
        "fmt"
    )
    
    func main() {
    
        //work(func() {
        //  fmt.Println("参与部门会议")
        //  fmt.Println("修改BUG")
        //  fmt.Println("完成老大安排的任务")
        //  fmt.Println("... ...")
        //  fmt.Println("提交代码")
        //})
    
        work(func() {
            fmt.Println("组织部门会议")
            fmt.Println("给部门的员工分配任务")
            fmt.Println("检查部门员工昨天提交的代码")
            fmt.Println("... ...")
        })
    }
    // 攻城狮的一天
    func work(method func()){
        // 1.上班前
        func(){
            fmt.Println("起床")
            fmt.Println("刷牙洗脸")
            fmt.Println("吃早餐")
            fmt.Println("做地铁")
            fmt.Println("打卡")
            fmt.Println("打开电脑")
        }()
    
        // 2.上班中
        method()
    
        // 3.下班之后
        func(){
            fmt.Println("关电脑")
            fmt.Println("打卡")
            fmt.Println("坐地铁")
            fmt.Println("到家")
            fmt.Println("吃饭")
            fmt.Println("娱乐")
            fmt.Println("刷牙洗脸")
            fmt.Println("睡觉")
        }()
    
    }
    
    // 项目经理的一天
    func work2(){
        fmt.Println("起床")
        fmt.Println("刷牙洗脸")
        fmt.Println("吃早餐")
        fmt.Println("做地铁")
        fmt.Println("打卡")
        fmt.Println("打开电脑")
    
        fmt.Println("组织部门会议")
        fmt.Println("给部门的员工分配任务")
        fmt.Println("检查部门员工昨天提交的代码")
        fmt.Println("... ...")
    
        fmt.Println("关电脑")
        fmt.Println("打卡")
        fmt.Println("坐地铁")
        fmt.Println("到家")
        fmt.Println("吃饭")
        fmt.Println("娱乐")
        fmt.Println("刷牙洗脸")
        fmt.Println("睡觉")
    }
    // 程序员的一天
    func work1()  {
        fmt.Println("起床")
        fmt.Println("刷牙洗脸")
        fmt.Println("吃早餐")
        fmt.Println("做地铁")
        fmt.Println("打卡")
        fmt.Println("打开电脑")
    
        fmt.Println("参与部门会议")
        fmt.Println("修改BUG")
        fmt.Println("完成老大安排的任务")
        fmt.Println("... ...")
        fmt.Println("提交代码")
    
        fmt.Println("关电脑")
        fmt.Println("打卡")
        fmt.Println("坐地铁")
        fmt.Println("到家")
        fmt.Println("吃饭")
        fmt.Println("娱乐")
        fmt.Println("刷牙洗脸")
        fmt.Println("睡觉")
    }
    

    5 闭包

    package main
    
    import "fmt"
    
    func main() {
        /*
        1.什么是闭包?
        闭包就是一个特殊的匿名函数
        只要匿名函数中用到了外界的变量, 那么我们就把匿名函数叫做闭包
    
        注意点:
        只要闭包还在使用外界的变量, 那么外界的变量就会一直存在
         */
    
         /*
         num := 10 // 11 12
         a := func() {
            num++
            fmt.Println(num)
         }
         a() // 11
         a() // 12
         a() // 13
         */
         // addUpper会返回一个闭包, 那么fn中保存的就是这个闭包, 那么fn就等于闭包
         // 所以按照Go语言的规则, 只要fn还在, addUpper中被闭包引用的变量就不会释放
         fn := addUpper()
         fn()
         fn()
         fn()
    }
    func addUpper() func() {
        x := 1
        return func() {
            x++
            fmt.Println(x) // 2 , 3 , 4
        }
    }
    

    相关文章

      网友评论

          本文标题:10 Go匿名函数 && 闭包

          本文链接:https://www.haomeiwen.com/subject/pxatoftx.html