zoukankan      html  css  js  c++  java
  • 闭包

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

    案例演示:

    package main
    import (
      "fmt"
    )

    //累加器
    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))   //11
      fmt.Println(f(2))   //13
      fmt.Println(f(3))   //16

    }

    对上面代码的说明和总结:

    1)AddUpper 是一个函数,返回的数据类型是func (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)我们要搞清楚闭包的关键,就是要分析出返回的函数它使用(引用)到哪些变量,因为函数和它引用到的变量共同构成闭包。

    6)对上面的代码的一个修改,加深对闭包的理解

    package main
    import (
    "fmt"
    )

    //累加器
    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)   //1.str="hello$" 2.str="hello$$" 3.str="hello$$$"
        return n
      }
    }

    func main() {
      //使用前面的代码
      f := AddUpper()
      fmt.Println(f(1))   //11
      fmt.Println(f(2))   //13
      fmt.Println(f(3))   //16
    }

    闭包的最佳实践:

    请编写一个程序,具体要求如下:

    1)编写一个函数 makeSuffix(suffix string) 可以接收一个文件后缀名(比如.jpg),并返回一个闭包

    2)调用闭包,可以传入一个文件名,如果该文件名没有指定的后缀(比如.jpg),则返回 文件名.jpg,如果已经有.jpg后缀,则返回源文件名。

    3)要求使用闭包的方式完成

    4)strings.HasSuffix

    函数HasSuffix:

      func HasSuffix(s, suffix string) bool
      判断s是否有后缀字符串suffix。


    代码:

    package main
    import (
    "fmt"
    "strings"
    )

    func makeSuffix(suffix string) func (string) string {
      return func (name string) string {
        //如果 name 没有指定后缀,则加上,否则就返回原来的名字
        if !strings.HasSuffix(name, suffix) {
          return name + suffix
        }
        return name
      }

    }

    func main() {

      //返回一个闭包
      f := makeSuffix(".jpg") //如果使用闭包完成,好处是只需要传入一次后缀
      //测试makeSuffix 的使用
      fmt.Println("文件名处理后=", f("winter"))
      fmt.Println("文件名处理后=", f("bird.jpg"))
    }


    代码说明:

    1)返回的匿名函数和 makeSuffix(suffix string) 里面的 suffix 变量 和返回的函数组合成一个闭包,因为返回的函数引用到suffix这个变量

    2)我们体会一下闭包的好处,如果使用传统的方法,也可以轻松实现这个功能,但是传统方法需要每次都传入 后缀名,比如.jpg,而闭包因为可以保留上次引用的某个值,所以我们传入一次就可以反复使用。

    传统方法的例子:

    func makeSuffix2(suffix string, name string) string {

      //如果 name 没有指定后缀,则加上,否则就返回原来的名字
      if !strings.HasSuffix(name, suffix) {
        return name + suffix
      }
      return name
    }

    func main() {

      fmt.Println("文件名处理后=", makeSuffix2("jpg","winter"))    //每次都得传后缀名
      fmt.Println("文件名处理后=", makeSuffix2("jpg","bird.jpg"))
    }

  • 相关阅读:
    小程序模板template问题记录
    datepicker 组件 的坑
    js实现 throttle 和 debounce
    vuex简单使用
    webpack 打包图片 缺失问题
    invalid prop `current` of type `string` supplied to `pagination`, expected `
    HTML5自定义属性之data-*
    vue组件传值方式介绍
    解决github.com 打不开问题
    git密令使用
  • 原文地址:https://www.cnblogs.com/green-frog-2019/p/11355085.html
Copyright © 2011-2022 走看看