闭包函数,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;
        }
    }
}
相关推荐
哪吒编程7 分钟前
从0.031秒优化0.018秒,JEP 483为Java应用带来的启动加速黑科技
java·后端
努力的搬砖人.13 分钟前
nacos配置达梦数据库驱动源代码步骤
java·服务器·数据库·经验分享·后端
风象南38 分钟前
SpringBoot中3种条件装配技术
java·spring boot·后端
唐青枫38 分钟前
如何用Go写一个benchmark 解析器及Web UI 数据可视化?
go
.生产的驴7 小时前
SpringBoot 接口限流Lua脚本接合Redis 服务熔断 自定义注解 接口保护
java·大数据·数据库·spring boot·redis·后端·lua
一切皆有迹可循7 小时前
SpringBoot整合MinIO快速入门:实现分布式文件存储与管理
spring boot·分布式·后端
洛可可白9 小时前
Spring Boot中自定义注解的创建与使用
java·spring boot·后端
追逐时光者9 小时前
一款 .NET 开源、免费、轻量级且非侵入性的防火墙软件
后端·.net
Asthenia041211 小时前
Netty ServerBootstrap Handler链与Pipeline分析
后端
uhakadotcom11 小时前
New Relic入门指南:性能监控与API应用
后端·面试·github