news 2026/6/23 11:55:14

Golang的函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Golang的函数

函数是Go语言中的基本构建块,用于组织可重用的代码逻辑。本文将详细介绍Go中函数的定义、参数传递、返回值以及高级用法。

1. 函数的基本格式

完整语法结构

func函数名(参数列表)(返回值列表){// 函数体return返回值}

组成部分说明

组成部分说明是否必需
func函数关键字必需
函数名标识函数名称必需
参数列表(参数名 参数类型, ...)可选
返回值列表(返回值名 返回值类型, ...)可选
函数体{ ... }必需
return返回语句根据返回值类型决定

2. 函数的参数传递

Go语言中的参数传递分为两种方式:值传递引用传递

值传递

值传递会将实参的值复制一份传递给函数,函数内部对参数的修改不会影响外部变量。

示例代码
packagemainimport"fmt"funcmain(){x:=12fmt.Printf("进入函数前,函数外部x的值为:%d\n",x)add(x)fmt.Printf("进入函数后,函数外部x的值还是:%d\n",x)}funcadd(xint)int{x+=12fmt.Printf("函数内部,x完成加12,值为:%d\n",x)returnx}

输出:

进入函数前,函数外部x的值为:12 函数内部,x完成加12,值为:24 进入函数后,函数外部x的值还是:12

原理分析:

外部变量 x = 12 | | 值传递:复制一份 12 ↓ 函数参数 x = 12 (独立副本) | | 函数内部修改 ↓ 函数内部 x = 24 | | 函数结束后副本销毁 ↓ 外部变量 x = 12 (不受影响)

引用传递

引用传递通过传递变量的内存地址(指针),函数内部通过指针修改数据会直接影响外部变量。

示例代码
packagemainimport"fmt"funcmain(){x:=12fmt.Printf("进入函数前,函数外部x的值为:%d\n",x)add2(&x)// 传递x的内存地址fmt.Printf("进入函数后,函数外部x的值变为:%d\n",x)}funcadd2(x*int)int{*x+=12// 通过指针修改值fmt.Printf("函数内部,x完成加12,值为:%d\n",*x)return*x}

输出:

进入函数前,函数外部x的值为:12 函数内部,x完成加12,值为:24 进入函数后,函数外部x的值变为:24

原理分析:

外部变量 x = 12 (内存地址: 0x1000) | | 引用传递:传递地址 0x1000 ↓ 函数参数 x = 0x1000 (指针) | | 通过地址修改内存 ↓ *操作符解引用,修改地址0x1000的值 | ↓ 外部变量 x = 24 (同一块内存被修改)

值传递 vs 引用传递对比

对比维度值传递引用传递(指针)
传递内容数据的副本数据的内存地址
内存占用复制整个数据只复制指针(8字节)
修改影响不影响外部变量影响外部变量
大对象性能开销较大开销较小
安全性高(不会意外修改外部数据)需要谨慎使用
语法标识直接传值使用&取地址和*解引用

3. 函数的参数类型

多个参数

funcadd(aint,bint)int{returna+b}// 连续参数类型可以简写funcadd(a,bint)int{returna+b}

可变参数

funcsum(nums...int)int{total:=0for_,num:=rangenums{total+=num}returntotal}// 调用方式result:=sum(1,2,3,4,5)// result = 15

4. 函数的返回值

单返回值

funcadd(aint,bint)int{returna+b}

多返回值

funcdivide(a,bint)(int,error){ifb==0{return0,fmt.Errorf("除数不能为零")}returna/b,nil}

命名返回值

funcgetCoordinates()(x,yint){x=10y=20return// 裸返回,自动返回x和y}

5. 匿名函数和闭包

匿名函数

// 定义并立即执行funcmain(){result:=func(a,bint)int{returna+b}(10,20)fmt.Println(result)// 30}

闭包(Closure)

funcgetCounter()func()int{count:=0returnfunc()int{count++returncount}}funcmain(){counter:=getCounter()fmt.Println(counter())// 1fmt.Println(counter())// 2fmt.Println(counter())// 3}

6. 函数作为类型

定义函数类型

typeOperationfunc(int,int)intfuncadd(a,bint)int{returna+b}funcsubtract(a,bint)int{returna-b}funcmain(){varop Operation op=add fmt.Println(op(10,5))// 15op=subtract fmt.Println(op(10,5))// 5}

函数作为参数

funccalculate(a,bint,opfunc(int,int)int)int{returnop(a,b)}funcmain(){result:=calculate(10,5,func(a,bint)int{returna*b})fmt.Println(result)// 50}

7. defer延迟执行

defer语句用于在函数返回前执行某些操作,常用于资源清理。

funcreadFile(){file,err:=os.Open("test.txt")iferr!=nil{return}deferfile.Close()// 函数返回前自动关闭文件// 读取文件内容...fmt.Println("读取文件成功")}

defer的特性

  • 多个defer按后进先出(LIFO)顺序执行
  • defer在函数返回之前执行
  • defer的参数在定义时就已经确定
funcdeferExample(){deferfmt.Println("第三")deferfmt.Println("第二")deferfmt.Println("第一")fmt.Println("开始执行")}// 输出:// 开始执行// 第一// 第二// 第三

8. init函数

init函数在包初始化时自动执行,用于初始化包级别的变量。

packagemainimport"fmt"funcinit(){fmt.Println("init函数执行")}funcmain(){fmt.Println("main函数执行")}// 输出:// init函数执行// main函数执行

9. 完整示例程序

packagemainimport"fmt"funcmain(){// 值传递示例fmt.Println("=== 值传递 ===")x:=12fmt.Printf("进入函数前,函数外部x的值为:%d\n",x)add(x)fmt.Printf("进入函数后,函数外部x的值还是:%d\n\n",x)// 引用传递示例fmt.Println("=== 引用传递 ===")y:=12fmt.Printf("进入函数前,函数外部y的值为:%d\n",y)add2(&y)fmt.Printf("进入函数后,函数外部y的值变为:%d\n\n",y)// 多返回值示例fmt.Println("=== 多返回值 ===")quotient,remainder:=divide(17,5)fmt.Printf("17 / 5 = %d 余 %d\n\n",quotient,remainder)// 闭包示例fmt.Println("=== 闭包示例 ===")counter:=getCounter()fmt.Println(counter())fmt.Println(counter())fmt.Println(counter())}// 值传递函数funcadd(xint)int{x+=12fmt.Printf("函数内部,x完成加12,值为:%d\n",x)returnx}// 引用传递函数(指针)funcadd2(x*int)int{*x+=12fmt.Printf("函数内部,x完成加12,值为:%d\n",*x)return*x}// 多返回值函数funcdivide(a,bint)(int,int){returna/b,a%b}// 闭包函数funcgetCounter()func()int{count:=0returnfunc()int{count++returncount}}
  1. 函数命名:使用驼峰命名法,导出函数首字母大写
  2. 单一职责:每个函数只做一件事
  3. 参数数量:尽量避免超过5个参数
  4. 错误处理:多返回error类型进行错误处理
  5. 避免副作用:尽量保持函数的纯粹性
  6. 适当注释:为导出的函数添加注释说明
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 11:47:46

轻集料混凝土哪家强?LC5.0型厂家这样选才靠谱

“垫层又要轻又要强,怎么选?”这句话背后,是无数项目经理和采购人员在面对卫生间回填、屋面找坡、地下室垫层等场景时的真实困惑。轻集料混凝土作为一种轻质高强的材料,近年来越来越受到建筑工程的青睐,尤其是LC5.0型这…

作者头像 李华
网站建设 2026/6/23 11:36:01

基于 Harmony 7.0 应用的手写签名应用首页实现

基于 Harmony 7.0 应用的手写签名应用首页实现 前言 电子签名已经成为无纸化办公的标配。从合同签署到文件审批,从报销单据到会议纪要——手写签名让电子文档具有了法律效力。一款好的手写签名工具,应该像一张无限大的签名纸——书写区域宽敞、签名流畅自…

作者头像 李华
网站建设 2026/6/23 11:34:59

AI领域每日资讯日报 | 2026年6月22日

📰 今日头条 1. 🏆 诺奖得主、AlphaFold之父投奔Anthropic!谷歌48小时连跑俩大将 Demis Hassabis(AlphaFold之父、诺贝尔奖得主)等谷歌顶尖AI人才集体跳槽Anthropic,引发业界震动。谷歌48小时内连失两员大将…

作者头像 李华
网站建设 2026/6/23 11:30:02

信托制物业缴费模式的数智化落地实践与技术架构

作为深耕物业行业20年的从业者,我们在全国12个城市的信托制物业试点中,通过构建"智能缴费中台物联网监管系统AI工单引擎"三位一体技术架构,实现了业主资金安全与服务质量的动态平衡。以下从技术落地角度,拆解五大核心问…

作者头像 李华
网站建设 2026/6/23 11:16:42

Windows热键冲突诊断利器:Hotkey Detective深度解析与实战应用

Windows热键冲突诊断利器:Hotkey Detective深度解析与实战应用 【免费下载链接】hotkey-detective A small program for investigating stolen key combinations under Windows 7 and later. 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective …

作者头像 李华