当前位置: 首页 > news >正文

GO语言中的回调函数

0.前言

回调函数是一种在编程中常见的技术,通常在异步编程中使用。简单来说,回调函数是一个被传递给另一个函数的函数,它在该函数的某个时间点被调用,以完成某些特定的操作或任务

在Go语言中,可以将函数直接作为参数传递给另一个函数,并在需要时被调用,这样大大的加强了代码的可定制化,但是也一定程度上减少了代码的可读性,所以在实际使用的时候要学会取舍。

1.使用

  • 异步编程:通常情况下,回调函数在异步操作完成后被调用,以便通知调用方该操作已完成或返回异步操作的结果,回调函数可定制化,所以可以做不同的一些工作。
  • 如果某种逻辑,有几种实现方法,那么可以使用回调函数,将实现和逻辑解耦,提高可复用性和可维护性。例如简易计算器和sort.Slice函数(在下面有代码演示)。

2.几个例子

2.1 异步访问URL

首先定义type callback func(data []byte, err error)作为回调函数的类型,随后写读取URL的逻辑(fetch函数),在主函数中,传入回调函数和URL,并通过channel异步地调用此函数,通过WaitGroup等待协程的返回,其中回调函数定义了读取的内容如何使用,是可定制的。

package mainimport ("fmt""io/ioutil""net/http""sync""time"
)type callback func(data []byte, err error)
var wg sync.WaitGroup
func fetch(url string, c callback) {go func() {// 发送HTTP GET请求resp, err := http.Get(url)if err != nil {c(nil, err)return}defer resp.Body.Close()// 读取响应数据data, err := ioutil.ReadAll(resp.Body)if err != nil {c(nil, err)return}time.Sleep(10*time.Second)// 调用回调函数,传递响应数据和错误信息c(data, nil)wg.Done()}()
}func main() {url := "https://www.baidu.com"wg.Add(1)fetch(url, func(data []byte, err error) {if err != nil {fmt.Println("Error:", err)return}fmt.Println(string(data))})fmt.Println("Waiting for response...")wg.Wait()
}

2.1 Sort.Slice函数

GO语言的Sort.Slice函数就使用了回调函数的思想,将比较大小的逻辑交给用户来实现,将代码的可定制化大大增强了,以下是一个使用的例子,将字符串按首字母大小进行排序:

package mainimport ("fmt""sort"
)func main() {strs := []string{"apple", "orange", "banana", "pear"}sort.Slice(strs, func(i, j int) bool {return strs[i] < strs[j]})fmt.Println(strs)
}

2.2 简易计算器

在此例子中,定义了一个type Operation func(int, int) int作为回调函数的类型,随后对此函数做了不同的实现,在主函数中,就可以直接传入函数名,即可完成不同的逻辑运算。

package mainimport "fmt"type Operation func(int, int) intfunc main() {// 加法运算result := calculate(10, 5, add)fmt.Println(result) // Output: 15// 减法运算result = calculate(10, 5, subtract)fmt.Println(result) // Output: 5// 乘法运算result = calculate(10, 5, multiply)fmt.Println(result) // Output: 50// 除法运算result = calculate(10, 5, divide)fmt.Println(result) // Output: 2
}// 计算函数,接受两个整数和一个运算函数作为参数,返回运算结果
func calculate(a, b int, op Operation) int {return op(a, b)
}// 加法函数,接受两个整数并返回它们的和
func add(a, b int) int {return a + b
}// 减法函数,接受两个整数并返回它们的差
func subtract(a, b int) int {return a - b
}// 乘法函数,接受两个整数并返回它们的积
func multiply(a, b int) int {return a * b
}// 除法函数,接受两个整数并返回它们的商
func divide(a, b int) int {return a / b
}

相关文章:

GO语言中的回调函数

0.前言 回调函数是一种在编程中常见的技术&#xff0c;通常在异步编程中使用。简单来说&#xff0c;回调函数是一个被传递给另一个函数的函数&#xff0c;它在该函数的某个时间点被调用&#xff0c;以完成某些特定的操作或任务。 在Go语言中&#xff0c;可以将函数直接作为参…...

28个案例问题分析---014课程推送页面逻辑整理--vue

一&#xff1a;背景介绍 项目开发过程中&#xff0c;前端出现以下几类问题&#xff1a; 代码结构混乱代码逻辑不清晰页面细节问题 二&#xff1a;问题分析 代码结构混乱问题 <template><top/><div style"position: absolute;top: 10px"><C…...

佛科院单片机原理2——80C51单片机结构

一、程序存储器的入口地址&#xff1a;程序入口地址&#xff1a;0000H外部中断0入口地址&#xff1a;0003H定时器0溢出中断入口地址&#xff1a;000BH外部中断1入口地址&#xff1a;00013H定时器1溢出中断入口地址&#xff1a;001BH串行口中断入口地址&#xff1a;0023H定时器2…...

数据结构与算法_动态顺序表

顺序表是线性表的一种。 线性表是n个具有相同特性的数据元素的有限序列。 逻辑上&#xff0c;它们是线性结构&#xff0c;是一条连续的直线&#xff1b;但是在物理上&#xff0c;它们通常以数组和链式结构存储。 常见的线性表有顺序表、栈、队列、字符串等。 顺序表是用一段…...

逃避浏览器JS检测打开开发者工具

20230304 - 0. 引言 看到一些视频网站之后&#xff0c;想把视频离线下载下来怎么办&#xff1f;直接的方法是通过开发者工具来查看网络流量&#xff0c;一般可以在传输的请求类型中搜索m3u8&#xff0c;然后找到这部分请求&#xff0c;然后利用某些播放器或者下载器直接下载。…...

ceph介绍、原理、架构、算法...个人学习记录

前言 之前公司安排出差支援非结构化项目&#xff0c;采用springcloud(redismysql数据冷热处理)s3escephkafka还涉及一些区块链技术等等…&#xff0c;在与大佬的沟通交流下对ceph产生了兴趣&#xff0c;私下学习记录一下&#xff1b;后续工作之余会采用上面相关技术栈手动实现不…...

Spring MVC源码解析——HandlerMapping(处理器映射器)

Sping MVC 源码解析——HandlerMapping处理器映射器1. 什么是HandlerMapping2. HandlerMapping2.1 HandlerMapping初始化2.2 getHandler解析3. getHandlerInternal()子类实现3.1 AbstractUrlHandlerMapping与AbstractHandlerMethodMapping的区别3.2 AbstractUrlHandlerMapping3…...

【Word/word2007】将标题第1章改成第一章

问题&#xff1a;设置多级列表没有其他格式选的解决办法和带来的插入图注解的问题&#xff0c;将标题第1章改成第一章的问题其他方案。 按照百度搜索的方法设置第一章&#xff0c;可以是没有相应的样式可以选。 那就换到编号选项 设置新的编号值 先选是 然就是变得很丑 这时打开…...

NLP预训练模型

Models Corpus RoBERTa: A Robustly Optimized BERT Pretraining Approach 与BERT主要区别在于&#xff1a; large mini-batches 保持总训练tokens数一致&#xff0c;使用更大的学习率、更大的batch size&#xff0c;adam β20.98\beta_20.98β2​0.98&#xff1b;dynamic ma…...

Typora上传文档图片链接失效的问题+PicGo布置图床在Github

文章目录typora图片链接失效原因PicGO开源图床布置先配置Github2.1先创建新仓库、用于存放图片2.2生成一个token&#xff0c;用picGo访问github3.下载picGo,并进行配置3.1 配置v4.1typora图片链接失效原因 因为你是保存在本地的&#xff0c;因此图片是不能访问&#xff0c;可以…...

win10安装oracle

文件放到最后。我的电脑是win11的&#xff0c;因为老师让写下安装笔记&#xff0c;在11上安装的时候没有截屏&#xff0c;所以在虚拟机上重新安装下吧。室友说要把文件夹放到c盘才能打开。我试了下&#xff0c;具体的是要把Oracle11g文件夹放到c盘根目录下。如果解压后不是这个…...

AQS为什么用双向链表?

首先&#xff0c;在AQS中&#xff0c;等待队列是通过Node类来表示的&#xff0c;每个Node节点包含了等待线程的信息以及等待状态。下面是Node类的部分源码&#xff1a;static final class Node {// 等待状态volatile int waitStatus;// 前驱节点volatile Node prev;// 后继节点…...

AtCoder Beginner Contest 292——A-E题讲解

蒟蒻来讲题&#xff0c;还望大家喜。若哪有问题&#xff0c;大家尽可提&#xff01; Hello, 大家好哇&#xff01;本初中生蒟蒻讲解一下AtCoder Beginner Contest 292这场比赛的A-E题&#xff01; A题 原题 Problem Statement You are given a string SSS consisting of lo…...

(蓝桥真题)最长不下降子序列(权值线段树)

样例输入&#xff1a; 5 1 1 4 2 8 5 样例输出&#xff1a; 4 分析&#xff1a;看到这种对其中连续k个数进行修改的我们就应该想到答案是由三部分组成&#xff0c;因为求的是最长不下降子序列&#xff0c;那么我们可以找到一个最合适的断点i&#xff0c;使得答案是由区间[1…...

数据类型及参数传递

1.数据类型 java中的基本数据类型: 数值型&#xff1a; 整数型&#xff1a;byte short long int 浮点型&#xff1a;float double 布尔型&#xff1a; boolean字符串: char java中的引用数据类型&#xff1a; 数组&#xff08;array&#xff09; 类&#xff08;class…...

永春堂1300系统开发|解析永春堂1300模式商城的五大奖项

电商平台竞争越来越激烈&#xff0c;各种营销方式也是层出不穷&#xff0c;其中永春堂1300营销模式&#xff0c;以其无泡沫和自驱动性强等特点风靡一时。在这套模式中&#xff0c;虽然单型价格差异较大&#xff0c;但各种奖励的设计&#xff0c;巧妙的兼顾了平台和所有会员的利…...

最近一年我都干了什么——反思!!

过去一年不管是学习方式还是心态上都和以往有了许多不同的地方&#xff0c;比较昏昏沉沉。最近慢慢找到状态了&#xff0c;就想赶紧记录下来。 学习 在学习新技术的过程中开始飘了&#xff0c;总感觉有了一些开发经验后就觉得什么都不用记&#xff0c;知道思路就行遇到了现场百…...

Docker学习(十七)save 和 export 命令的区别

Docker 中有两个命令可以将镜像导出为本地文件系统中的 tar 文件&#xff1a;docker save 和 docker export。尽管它们的作用类似&#xff0c;但它们之间有一个重要的区别。 1.使用方式的不同&#xff1a; docker save 的使用示例&#xff1a; docker save -o test.tar image…...

【数据结构初阶】详解“树”

目录 前言 1.树概念及结构 &#xff08;1&#xff09;树的概念 &#xff08;2&#xff09;树的名词介绍 &#xff08;3&#xff09;树的表示 ​编辑 2.二叉树概念及结构 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;特殊的二叉树 &#xff08;3&#xff0…...

20230304 CF855 div3 vp

Dashboard - Codeforces Round 855 (Div. 3) - Codeforces呃呃&#xff0c;评价是&#xff0c;毫无进步呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃呃该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训了该加训…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

Windows 下端口占用排查与释放全攻略

Windows 下端口占用排查与释放全攻略​ 在开发和运维过程中&#xff0c;经常会遇到端口被占用的问题&#xff08;如 8080、3306 等常用端口&#xff09;。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口&#xff0c;帮助你高效解决此类问题。​ 一、准…...