Go语言基础10——匿名函数和闭包

一、匿名函数

函数还可以作为返回值,但是在Go语言中不能再像之前那样定义函数了,只能定义匿名函数。匿名函数就是没有函数名的函数。
闭包 = 函数 + 外层变量的引用

一、调用匿名函数的方法

package main
import "fmt"

// 匿名函数与闭包
func main() {
    // 将匿名函数保存到变量
    add := func(a, b int){
        fmt.Println(a + b)
    }
    add(10, 20) // 通过变量调用匿名函数

    // 自执行函数: 匿名函数定义完加()直接执行
    func(a, b int){
        fmt.Println(a - b)
    }(30, 20)
}

二、闭包示例1

package main
import "fmt"

// 闭包 = 函数 + 引用环境
func adder() func(int) int{
    var x int
    return func(y int) int{
        x += y
        return x
    }
}

func main(){
    // f是一个闭包: 
    // 1. f是一个函数
    // 2. f引用了其外部作用域中的x变量
    // 在f的生命周期内 变量x一直有效
    f := adder()
    fmt.Println(f(10))
    fmt.Println(f(20))
    fmt.Println(f(30))
    f1 := adder()
    fmt.Println(f1(2000))
    fmt.Println(f1(5000))
}

三、闭包示例2

package main
import "fmt"

// 闭包 = 函数 + 外层变量的引用
func adder2(x int) func(int) int{
    return func(y int) int{
        x += y
        return x
    }
}

func main(){
    f := adder2(0)
    fmt.Println(f(10))
    fmt.Println(f(20))
    fmt.Println(f(30))
    f1 := adder2(1000)
    fmt.Println(f1(2000))
    fmt.Println(f1(5000))
}

四、闭包示例3

package main
import (
    "fmt"
    "strings"
)

func makeSuffixFunc(suffix string) func(string) string{
    return func(name string) string{
        if !strings.HasSuffix(name, suffix){
            return name + suffix
        }
        return name
    }
}

func main() {
    jpgFunc := makeSuffixFunc(".jpg")
    txtFunc := makeSuffixFunc(".txt")
    fmt.Println(jpgFunc("test")) // test.jpg
    fmt.Println(txtFunc("test")) // test.txt
}

五、闭包示例4

package main
import "fmt"

func calc(base int) (func(int) int, func(int) int){
    add := func(i int) int{
        base += i
        return base
    }

    sub := func(i int) int{
        base -= i
        return base
    }
    return add, sub
}

func main(){
    f1, f2 := calc(10)
    f3, f4 := calc(30)
    fmt.Println(f1(1), f2(2)) // 11 9
    fmt.Println(f1(3), f2(4)) // 12 8
    fmt.Println(f3(5), f4(6)) // 35 29
    fmt.Println(f1(5), f2(6)) // 13 7
}

六、panic与recover

package main
import "fmt"

// panic和recover
func a(){
    fmt.Println("func a")
}

func b(){
    defer func(){
        // recover()必须搭配defer使用
        // defer必须在可能引发panic的语句之前定义
        err := recover()
        if err != nil{
            fmt.Println("func b error")
        }
    }()
    panic("panic in b")
}

func c(){
    fmt.Println("func c")
}

func main() {
    a()
    b()
    c()
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容