闭包函数,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;
        }
    }
}
相关推荐
2401_857622661 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589361 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
哎呦没2 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch3 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
杨哥带你写代码4 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
AskHarries5 小时前
读《show your work》的一点感悟
后端
A尘埃5 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-23075 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code5 小时前
(Django)初步使用
后端·python·django
代码之光_19805 小时前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端