go 闭包

  • 基本介绍

闭包就是一个函数和与其相关的引用环境组合的一个整体(实体)

案例:

package main

import (
    "fmt"
)

//累加器函数 (返回的是一个匿名函数func (int) int)
func AddUpper() func(int) int {
    var n int = 10
    return func(x int) int {
        n = n + x
        return n
    }
}

func main() {
    f := AddUpper()
    fmt.Println(f(1))
    fmt.Println(f(2))
    fmt.Println(f(3))
    fmt.Println(AddUpper()(10))
    fmt.Println(AddUpper()(20))
}

说明:
1、AddUpper是一个函数,返回的数据类型是fun (int) int
2、闭包的说明

    var n int = 10
    return func(x int) int {
        n = n + x
        return n
    }

返回的是一个匿名函数,匿名函数引用到函数外的n ,因此这个匿名函数和n就形成了一个整体,构成闭包。

3、这样理解:闭包是一个类,函数是操作,n是字段 函数和它使用到的n构成一个闭包
4、当我们反复的调用f函数时,n只会初始化一次,因些每调用一次就会累加。
5、闭包的关键就是要分析出返回的函数它使用(引用到的变量),因为函数和它引用到的变量共同构成闭包。

//累加器函数 (返回的是一个函数func (int) int)
func AddUpper() func(int) int {
    var n int = 10
    var str = "hello"
    return func(x int) int {
        n = n + x
        str += string(36)
        fmt.Println("str=", str)
        return n
    }
}
func main() {
    f := AddUpper()
    fmt.Println(f(1))
    fmt.Println(f(2))
    fmt.Println(f(3))
    fmt.Println(AddUpper()(10))
    fmt.Println(AddUpper()(20))
}
  • 最佳实践

1、编写函数 makeSuffix(suffix string),可以接收一个文件后缀名(比如.jpg),并返回一个闭包
2、调用闭包,传入一个文件名,如果没有指定后缀,则返回 文件名.jpg,如果有后缀,则返回文件名
3、全用strings.hasSuffix 函数来判断某个字符串是否有指定的后缀。

package main
import (
    "fmt"
    "strings"
)

//编写函数 makeSuffix(suffix string),可以接收一个文件后缀名(比如.jpg),并返回一个闭包
//调用闭包,传入一个文件名,如果没有指定后缀,则返回 文件名.jpg,如果有后缀,则返回文件名
//全用 strings.hasSuffix 函数来判断某个字符串是否有指定的后缀。

func makeSuffix(suffix string) func(string) string {
    return func(name string) string {
        //如果name没有后缀,则name + suffix
        if !strings.HasSuffix(name, suffix) {
            return name + suffix
        }
        //如果有就直接 返回 name
        return name
    }
}
func main() {
    f := makeSuffix(".jpg")
    fmt.Println("文件名是:", f("cat"))
    fmt.Println("文件名是:", f("bird.jpg"))
    fmt.Println("文件名是:", f("mouse.avi"))
    fmt.Println("文件名是:", makeSuffix(".mp3")("song.mp3.mp4"))
}

说明:
1、返回的匿名函数引用到了 makeSuffix(suffix string) 函数的suiffix变量,形成了一个闭包。
2、我们体会一下闭包的好处,使用传统的方式,每次都要传入一个后缀名,(除非用全局变量),使用闭包的好处是,可以不用全局变量,不用反复传入后缀名.jpg
3、

你可能感兴趣的:(go 闭包)