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

深入理解 Go 函数:从基础到高级

一、函数基础

1、函数定义
  • 函数是组织好的、可重复使用的、用于执行指定任务的代码块
  • Go 语言中支持:函数、匿名函数和闭包
package mainimport "fmt"func main(){ret := intSum(1,2)fmt.PrintIn(ret)    //3
}func instSum(x,y int) int {return x + y
}
2、可变参数
  • 可变参数是指函数的参数数量不固定
  • Go 语言中的可变参数通过在参数名后加...来标识
  • 注意:可变参数通常摇作为函数的最后一个参数
package main
import "fmt"
func main() {ret := intSum("Snail",2,3,4,5)fmt.Println(ret)      // 14
}
func intSum(y string,x ...int) int {fmt.Println(y)       // Snailfmt.Println(x)       //x 是一个切片 => [1 2 3 4 5]sum := 0for _, v := range x {sum = sum + v}return sum
}
3、函数返回值
  • Go 语言中通过 return 关键字向外输出返回值
  • 函数多返回值,Go 语言中函数支持多返回值,函数如果有多个返回值是必须用()将所有返回值包裹起来
package main
import "fmt"
func main() {plus,sub := calc(4,5)fmt.Println(plus)      // 和为:9fmt.Println(sub)       // 差为:-1
}
func calc(x, y int) (int, int) {sum := x + ysub := x - yreturn sum, sub
}
4、函数类型与变量
  • 定义函数类型,我们可以使用 type 关键字来定义一个函数类型
  • 具体格式如下
type calculation func(int, int) int
  • 上面语句定义了一个 calculation 类型,它是一种函数类型,这种函数接收两个 int 类型的参数并且返回一个 int 类型的返回值
  • 简单来说,凡是满足这个条件的函数哦都市 calc 类型的函数,例如下面的 add 和 sub 是 calculation 类型
package mainimport "fmt"type calc func(int,int) intfunc main(){var c calc    //声明一个 calc 类型的变量 cc = add    //把 add 赋值给 cfmt.PrintIn(c(1,2))    //3//fmt.Printf("type of c:%T\n", c)  // type of c:main.calculation
}func add(x, y int) int {return x + y
}

二、函数变量作用域

1、全局变量
  • 全局变量是定义在函数外部的变量,他在程序整个运行周期内都有效
  • 在函数中可以访问到全局变量
package mainimport "fmt"//定义全局变量 num
var num int64 = 10
func main() {fmt.Printf("num=%d\n",num)    //num=10
}
2、局部变量
  • 局部变量是函数内部定义的变量,函数内定义的变量无法在该函数外使用
  • 例如下面额示例代码 main 函数中无法使用 test 函数中定义的变量 x
package mainimport "fmt"func main(){//这是name 是函数 test 的局部变量,在其他函数内无法访问//fmt.PrintIn(name)
}func test() {name :="Snail"fmt.PrintIn(name)
}
3、语句块定义的变量
  • 接下来我们来看一下语句块定义的变量,通常我们会在 if 条件判断,for 循环、switch 语句上使用这种定义变量的方式
package mainimport "fmt"func main() {test2(1,2)
}func test2(x, y int) {fmt.PrintIn(x, y)    //函数的参数也是只在本函数中生效if x > 0 {z := 100    //变量 z 只在 if 语句生效fmt.PrintIn(z)}//fmt.Println(z)//此处无法使用变量 z
}

4、for 循环语句中定义的变量

  • 我们之前讲过的 for 循环语句中定义的变量,也是只在 for 语句块中生效
package main
import "fmt"
func main() {test3()
}
func test3() {for i := 0; i < 10; i++ {fmt.Println(i) //变量 i 只在当前 for 语句块中生效}// fmt.Println(i)  //此处无法使用变量 i
}

三、高阶函数

  • 高阶函数分为函数作为参数和函数作为返回值两部分
  • 函数作为参数,函数也可以作为返回值
package main
import "fmt"func main() {var a = do("+")fmt.Println(a(10, 20))   // 30var b = do("-")fmt.Println(b(10,20))    // -10
}func add(x, y int) int {return x + y
}
func sub(x, y int) int {return x - y
}
func do(s string) func(int, int) int {switch s {case "+":return addcase "-":return subdefault:return nil}
}

四、匿名函数

  • 匿名函数由一个不带函数名的函数声明和函数体组成
  • 匿名函数的优越性在于可以直接使用函数内的变量,不必申明
  • 匿名函数因为没有函数名,所以没办法像普通函数那样调用,所有匿名函数需要保存到某个变量或者作为立即执行函数
  • 匿名函数多用于实现回调函数和闭包
package main
import "fmt"func main() {//一:匿名函数  匿名自执行函数func() {fmt.Println("test..")    // test..}()//二:匿名函数var fn = func(x, y int) int {return x * y}fmt.Println(fn(2, 3))  // 6//三:匿名自执行函数接收参数func(x, y int) {fmt.Println(x + y)  // 30}(10, 20)
}

五、闭包

1、闭包的概念
  • 闭包可以理解成“定义在一个函数内部的函数”
  • 在本质上,闭包是将函数内部和函数外部连接起来的桥梁
  • 举例:
    • 变量 f 是一个函数并且它引用了其外部作用域中的 x 变量,此时 f 就是一个闭包
    • 在 f 的生命周期内,变量 x 也一直有效
package mainimport "fmt"func main() {var f = adder()fmt.PrintIn(f(10))    //10fmt.PrintIn(f(20))    //20fmt.PrintIn(f(30))    //30f1 := adder()fmt.Println(f1(40)) //40fmt.Println(f1(50)) //90
}func adder ()func(int) int {var x intreturn func(y int) int {x +=yreturn x}
}
2、闭包变量作用域
  • 全局变量特点:
    • 常驻内存
    • 污染全局
  • 局部变量的特点:
    • 不常驻内存
    • 不污染全局
  • 闭包:
    • 可以让一个变量常驻内存
    • 可以让一个变量不污染全局
    • 闭包是指有权访问另一个函数作用域中的变量的函数
    • 创建闭包的常见的方式就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量
  • 注意:
    • 由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所有可能会占用更多的内存
    • 过度使用闭包会导致性能下降,建议在非常有必要的时候才使用闭包
3、闭包的三种形式
1、闭包的进阶示例 1
package mainimport "fmt"func adder2(x int) func(int) int{returu func(y int) int {x += yreturn x}
}func main() {var f = adder2(10)fmt.Println(f(10)) //20fmt.Println(f(20)) //40fmt.Println(f(30)) //70f1 := adder2(20)fmt.Println(f1(40)) //60fmt.Println(f1(50)) //110
}
2、闭包进阶示例 2
package mainimport ("fmt""strings"
)
func makeSuffixFunc(suffix string) func(string) string {return func(name string) string {if !strings.HasSuffix(name, suffix) {return name + suffix}return name}
}
func main() {jpgFunc := makeSuffixFunc(".jpg")txtFunc := makeSuffixFunc(".txt")fmt.Println(jpgFunc("test")) //test.jpgfmt.Println(txtFunc("test")) //test.txt
}
3、闭包进阶示例 3
package main
import ("fmt"
)
func calc(base int) (func(int) int, func(int) int) {add := func(i int) int {base += ireturn base}sub := func(i int) int {base -= ireturn base}return add, sub
}
func main() {f1, f2 := calc(10)fmt.Println(f1(1), f2(2)) //11 9fmt.Println(f1(3), f2(4)) //12 8fmt.Println(f1(5), f2(6)) //13 7
}

相关文章:

深入理解 Go 函数:从基础到高级

一、函数基础 1、函数定义 函数是组织好的、可重复使用的、用于执行指定任务的代码块Go 语言中支持&#xff1a;函数、匿名函数和闭包 package mainimport "fmt"func main(){ret : intSum(1,2)fmt.PrintIn(ret) //3 }func instSum(x,y int) int {return x y }…...

开启三层交换机DHCP服务

二层交换机上不需要配置任何东西&#xff0c;只需要在pc机上开启dhcp服务&#xff0c;配置好LSW1后就可以自动获取到IP地址。 sys Enter system view, return user view with CtrlZ. [Huawei]sys sw1 [sw1]dhcp enable Info: The operation may take a few seconds. Please wai…...

jspdf+html2canvas浏览器缩放问题

之前在弄页面导出为pdf的时候,jspdf配合html2canvas貌似很好用,我自己在使用的时候也没有觉得有什么问题,但是客户那边反馈说下载下来的pdf不全. 后来问了客户才发现客户的浏览器比例缩放到了125%;这就导致了pdf不全, 先看看原来的代码: download() {let jsPDF jspdf.jsPDF;l…...

西南科技大学模拟电子技术实验六(BJT电压串联负反馈放大电路)预习报告

一、计算/设计过程 BJT电压串联负反馈放大电路图1-1-1-1为BJT电压串联负反馈放大实验电路,若需稳定输出电压,减小从信号源所取电流,可引入电压串联负反馈闭合开关。 图1-1-1-1 理论算法公式(1)闭环电压放大倍数 (2)反馈系数 (3)输入电阻 (4)输出电阻 计算过程。开环…...

JS的监听事件

在JavaScript中&#xff0c;你可以使用监听器来捕获和处理不同类型的事件。通过添加事件监听器&#xff0c;你可以指定当特定事件发生时要执行的函数。 以下是几种常见的监听事件的方法&#xff1a; 1. addEventListener()&#xff1a;用于在目标元素上添加事件监听器。它接受…...

JS Object.values()

一、官方定义 返回一个给定对象的自有可枚举字符串键属性值组成的数组 二、语法 Object.values(obj)参数 obj 被返回可枚举属性值的对象。返回值 一个包含对象自身的所有可枚举属性值的数组。描述 Object.values() 返回一个数组&#xff0c;其元素是在对象上找到的可枚举…...

基于Java SSM人力资源管理系统

人力资源管理系统实现对企业人力资源的科学管理。企业有多个部门&#xff0c;每个部门有——名经理和多名员工&#xff0c;公司设置多级岗位&#xff0c;对应不同薪酬标准&#xff0c;员工日常工作进行考勤&#xff0c;岗位变动需要进行登记。系统管理的对象及操作主要有&#…...

人工智能和程序员

一、介绍人工智能和程序员 人工智能&#xff08;AI&#xff09;是一种模拟人类智能的计算机系统&#xff0c;其目的是让计算机具备类似人类的学习、推理、规划和理解能力。人工智能致力于创建能够感知、适应环境并作出决策的智能体&#xff0c;以解决各种复杂的问题。程序员是…...

Unity优化篇:对于unity DrawCall/Mesh/纹理压缩/内存等方面的常规调试和优化手段

对于Unity的DrawCall、Mesh、纹理压缩、内存等方面的常规调试和优化手段&#xff0c;我都有一定的了解。以下是一些常见的优化手段&#xff1a; 减少DrawCall&#xff1a;这是提高性能的关键。尽可能合并相同的材质和纹理&#xff0c;使用LOD&#xff08;Levels of Detail&…...

学生信息管理系统

摘 要 学生成绩管理系统是典型的信息管理系统(MIS)&#xff0c;其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。经过分析&#xff0c;我们使用Microsoft公司的C语言开发工具&#xff0c;将与C语言技术与数据库SQL2008相结合进行设计。首先&#xff0c;…...

纯代码压缩WordPress前端Html

易于阅读的前端代码对开发而言是无比重要的&#xff0c;但对于浏览器来说就显得无比鸡肋了&#xff0c;毕竟浏览器不是像人眼一样看代码&#xff0c;过多的换行和空格&#xff0c;对前台加载是有一定影响的&#xff0c;对使用大带宽高配置服务器的网站&#xff0c;这么点影响可…...

Elasticsearch分词器--空格分词器(whitespace analyzer)

介绍 文本分析&#xff0c;是将全文本转换为一系列单词的过程&#xff0c;也叫分词。analysis是通过analyzer(分词器)来实现的&#xff0c;可以使用Elasticearch内置的分词器&#xff0c;也可以自己去定制一些分词器。除了在数据写入时将词条进行转换&#xff0c;那么在查询的时…...

【LeetCode】692. 前K个高频单词

692. 前K个高频单词 描述示例解题思路及事项思路一思路二 描述 给定一个单词列表 words 和一个整数 k &#xff0c;返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率&#xff0c; 按字典顺序 排序 示例 示例1 输…...

在Windows操作系统上使用rtsp simple server和ffmpeg推送录屏视频流

大纲 1 搭建启动rtsp server2 推送录屏视频流下载FFmpeg 3 检验3.1 获取本机IP3.2 检测 1 搭建启动rtsp server 从https://github.com/aler9/rtsp-simple-server/releases下载Windows版本的编译结果。 解压&#xff0c;然后启动该程序 2 推送录屏视频流 下载FFmpeg 从htt…...

互联网摸鱼日报(2023-12-05)

互联网摸鱼日报(2023-12-05) 36氪新闻 魔珐科技创始人兼CEO柴金祥&#xff1a;3D虚拟人原生产品&#xff0c;正在押注时代的“最大红利”| WISE2023商业之王大会 上市就来割韭菜&#xff1f;数十家在审企业也有“掏空式分红”之嫌&#xff0c;此前多家企业已惹众怒 历史新高…...

Android 项目的依赖方式

四种依赖方式 在 Android 项目中&#xff0c;有多种方式可以添加项目依赖。以下是几种常见的方式&#xff1a; Gradle 依赖&#xff1a;这是最常用和推荐的方式。在项目的 build.gradle 文件中&#xff0c;你可以使用 dependencies 块来添加依赖项。Gradle 会自动从远程仓库下…...

ArcGIS提取DEM中的山脉范围

已知数据&#xff1a;DEM文件ASTGTM_N00E118E.img 使用软件&#xff1a;ArcMap 要求&#xff1a;对数据进行操作&#xff0c;提取数据文件中的山脉范围 下面开始操作&#xff1a; 1、 打开ArcMap将DEM文件ASTGTM_N00E118E.img添加到数据框。 2、 接下来我们打开spatial ana…...

漏洞复现--万户ezoffice wpsservlet任意文件上传

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…...

TCPDUMP抓包明确显示IP地址和端口号

经常使用tcpdump进行抓包的同学可以忽略了&#xff0c;这篇偏于使用扫盲&#xff1b;首先&#xff0c;tcpdump抓包目的IP显示为hostname&#xff0c;如果端口是知名端口&#xff0c;显示为协议名而不是端口号。这种默认其实略有问题的&#xff1a; 如果我们使用默认的hostname…...

java FTP客户端获取文件流假死问题

依赖 hutool FTP配置 inspection.data.ftp.host172.26.1.41 inspection.data.ftp.port21 inspection.data.ftp.user6c inspection.data.ftp.password6cqq123 inspection.data.ftp.charsetNameGBK FTP配置类 import lombok.Data; import org.springframework.boot.context.pr…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...