闭包函数,Golang闭包的用法

嘿,你知道闭包是啥吗?就好比你的保温杯,一直记着你上次倒的咖啡温度。在 Go 语言中,闭包就像一个小助手,负责记住某个任务的状态。

比如,你有个任务是数羊(当然是为了入睡),闭包就是一个数羊的助手。他每数一只羊,就在心里记一下,下次再数的时候,继续从上次数到的羊数开始。这个助手就像是一个小精灵,一直默默地记录着你数了多少只羊。

go 复制代码
import "fmt"

func sheepCounter() func() int{
    count := 0
    return func() int{
        count++
        return count
    }
}

func main(){
    countSheep := sheepCounter()
    
    fmt.Println(countSheep())	// 输出 1
    fmt.Println(countSheep())	// 输出 2
    fmt.Println(countSheep())	// 输出 3
}

下面会详细解释为什么会输出 1 2 3

闭包是函数的返回值,也可以一种函数值,它引用了函数体外的变量。在 Go 中,函数可以是闭包,这意味着它可以访问并保留在其作用域之外定义的变量。这种特性使得函数可以作为函数参数传递,用于构建灵活的代码结构。

基本概念

  1. 函数是第一类公民:在 Go 中,函数是第一类公民,可以像其他值一样传递和使用。这使得函数可以作为参数传递给其他函数,也可以作为函数的返回值。
  2. 捕获外部变量:闭包可以访问并捕获在其作用域之外定义的变量。这些变量的值在闭包内部被保留,即使外部函数执行完毕,闭包仍然可以使用这些变量。

示例

1、计数器
go 复制代码
import "fmt"

func sheepCounter() func() int{
    count := 0
    return func() int{
        count++
        return count
    }
}

func main(){
    countSheep := sheepCounter()
    
    fmt.Println(countSheep())	// 输出 1
    fmt.Println(countSheep())	// 输出 2
    fmt.Println(countSheep())	// 输出 3
}
  • 外部函数sheepCounter的定义
go 复制代码
func sheepCounter() func() int{

sheepCounter 函数返回一个函数,该函数的签名是 func() int,即它没有参数,返回一个整数。

  • 内部函数的定义
go 复制代码
count := 0
return func() int{
    count++
    return count
}

sheepCounter 函数内部定义了一个局部变量 count,用于存储计数器的当前值。

返回的是一个匿名函数(闭包),该函数不接受参数,但在每次调用时递增 count 变量的值,并返回递增后的值。

  • 计数器的使用
go 复制代码
countSheep := sheepCounter()
fmt.Println(countSheep()) // 输出: 1
fmt.Println(countSheep()) // 输出: 2
fmt.Println(countSheep()) // 输出: 3

main 函数中,创建了一个计数器 countSheep,它实际上是调用 sheepCounter 函数后返回的闭包。

每次调用 countSheep(),闭包会递增 count 变量的值,并返回递增后的计数器值。

由于闭包中捕获了外部函数sheepCounter中的count变量,该变量的生命周期得以延续,不受外部函数执行完毕的影响。这样,每次调用闭包时,都会在原有计数器值得基础上递增,实现了一个简单的计数器功能。

2、函数工厂
go 复制代码
package main

import "fmt"

func multiplier(factor int) func(int) int {
	return func(x int) int {
		return x * factor
	}
}

func main(){
    double := multiplier(2)
    triple := multiplier(3)
    
    fmt.Println(double(5)) // 输出: 10
    fmt.Println(triple(5)) // 输出: 15
}

这个例子中,multiplier 函数返回一个闭包,用于创建乘法器。通过创建不同的闭包,可以轻松地生成具有不同乘数的乘法器函数。

以上就是关于Go语言闭包的所有内容,如果对你有帮助,点赞收藏加关注~

tips:

如何加快对语言的理解?多敲案例,案例简单,也许手脑一起动~

Java选手看一下这个案例,或许会眼前一亮~

java 复制代码
public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter(0);
        System.out.println(counter.countAdd());
        System.out.println(counter.countAdd());
        System.out.println(counter.countAdd());

        Counter co1 = new Counter(2);
        Counter co2 = new Counter(3);
        System.out.println(co1.multiplier(5));
        System.out.println(co2.multiplier(5));
    }
    public static class Counter{
        private Integer count;

        public Integer countAdd(){
            return count++;
        }

        public Integer multiplier(Integer x){
            return count * x;
        }

        public Counter() {
        }

        public Counter(Integer count) {
            this.count = count;
        }

        public Integer getCount() {
            return count;
        }

        public void setCount(Integer count) {
            this.count = count;
        }
    }
}
相关推荐
武子康1 小时前
Java-72 深入浅出 RPC Dubbo 上手 生产者模块详解
java·spring boot·分布式·后端·rpc·dubbo·nio
椰椰椰耶3 小时前
【Spring】拦截器详解
java·后端·spring
brzhang4 小时前
我操,终于有人把 AI 大佬们 PUA 程序员的套路给讲明白了!
前端·后端·架构
wan_da_ren6 小时前
JVM监控及诊断工具-GUI篇
java·开发语言·jvm·后端
【本人】6 小时前
Django基础(一)———创建与启动
后端·python·django
lifallen7 小时前
Kafka 时间轮深度解析:如何O(1)处理定时任务
java·数据结构·分布式·后端·算法·kafka
mCell7 小时前
Webhook:连接、自动化与系统集成的新范式
ci/cd·go·github
你的人类朋友7 小时前
【✈️速通】什么是SIT,什么是UAT?
后端·单元测试·测试
程序无bug9 小时前
后端3行代码写出8个接口!
java·后端
绝无仅有9 小时前
使用LNMP一键安装包安装PHP、Nginx、Redis、Swoole、OPcache
后端·面试·github