深入理解 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 语言中支持:函数、匿名函数和闭包 package mainimport "fmt"func main(){ret : intSum(1,2)fmt.PrintIn(ret) //3 }func instSum(x,y int) int {return x y }…...
开启三层交换机DHCP服务
二层交换机上不需要配置任何东西,只需要在pc机上开启dhcp服务,配置好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中,你可以使用监听器来捕获和处理不同类型的事件。通过添加事件监听器,你可以指定当特定事件发生时要执行的函数。 以下是几种常见的监听事件的方法: 1. addEventListener():用于在目标元素上添加事件监听器。它接受…...
JS Object.values()
一、官方定义 返回一个给定对象的自有可枚举字符串键属性值组成的数组 二、语法 Object.values(obj)参数 obj 被返回可枚举属性值的对象。返回值 一个包含对象自身的所有可枚举属性值的数组。描述 Object.values() 返回一个数组,其元素是在对象上找到的可枚举…...
基于Java SSM人力资源管理系统
人力资源管理系统实现对企业人力资源的科学管理。企业有多个部门,每个部门有——名经理和多名员工,公司设置多级岗位,对应不同薪酬标准,员工日常工作进行考勤,岗位变动需要进行登记。系统管理的对象及操作主要有&#…...
人工智能和程序员
一、介绍人工智能和程序员 人工智能(AI)是一种模拟人类智能的计算机系统,其目的是让计算机具备类似人类的学习、推理、规划和理解能力。人工智能致力于创建能够感知、适应环境并作出决策的智能体,以解决各种复杂的问题。程序员是…...
Unity优化篇:对于unity DrawCall/Mesh/纹理压缩/内存等方面的常规调试和优化手段
对于Unity的DrawCall、Mesh、纹理压缩、内存等方面的常规调试和优化手段,我都有一定的了解。以下是一些常见的优化手段: 减少DrawCall:这是提高性能的关键。尽可能合并相同的材质和纹理,使用LOD(Levels of Detail&…...
学生信息管理系统
摘 要 学生成绩管理系统是典型的信息管理系统(MIS),其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。经过分析,我们使用Microsoft公司的C语言开发工具,将与C语言技术与数据库SQL2008相结合进行设计。首先,…...
纯代码压缩WordPress前端Html
易于阅读的前端代码对开发而言是无比重要的,但对于浏览器来说就显得无比鸡肋了,毕竟浏览器不是像人眼一样看代码,过多的换行和空格,对前台加载是有一定影响的,对使用大带宽高配置服务器的网站,这么点影响可…...
Elasticsearch分词器--空格分词器(whitespace analyzer)
介绍 文本分析,是将全文本转换为一系列单词的过程,也叫分词。analysis是通过analyzer(分词器)来实现的,可以使用Elasticearch内置的分词器,也可以自己去定制一些分词器。除了在数据写入时将词条进行转换,那么在查询的时…...
【LeetCode】692. 前K个高频单词
692. 前K个高频单词 描述示例解题思路及事项思路一思路二 描述 给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序 示例 示例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版本的编译结果。 解压,然后启动该程序 2 推送录屏视频流 下载FFmpeg 从htt…...
互联网摸鱼日报(2023-12-05)
互联网摸鱼日报(2023-12-05) 36氪新闻 魔珐科技创始人兼CEO柴金祥:3D虚拟人原生产品,正在押注时代的“最大红利”| WISE2023商业之王大会 上市就来割韭菜?数十家在审企业也有“掏空式分红”之嫌,此前多家企业已惹众怒 历史新高…...
Android 项目的依赖方式
四种依赖方式 在 Android 项目中,有多种方式可以添加项目依赖。以下是几种常见的方式: Gradle 依赖:这是最常用和推荐的方式。在项目的 build.gradle 文件中,你可以使用 dependencies 块来添加依赖项。Gradle 会自动从远程仓库下…...
ArcGIS提取DEM中的山脉范围
已知数据:DEM文件ASTGTM_N00E118E.img 使用软件:ArcMap 要求:对数据进行操作,提取数据文件中的山脉范围 下面开始操作: 1、 打开ArcMap将DEM文件ASTGTM_N00E118E.img添加到数据框。 2、 接下来我们打开spatial ana…...
漏洞复现--万户ezoffice wpsservlet任意文件上传
免责声明: 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…...
TCPDUMP抓包明确显示IP地址和端口号
经常使用tcpdump进行抓包的同学可以忽略了,这篇偏于使用扫盲;首先,tcpdump抓包目的IP显示为hostname,如果端口是知名端口,显示为协议名而不是端口号。这种默认其实略有问题的: 如果我们使用默认的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…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
