news 2026/8/24 9:26:17

Go之路 - 7.go的函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Go之路 - 7.go的函数

一、函数基础

1.1 函数声明

// 基本语法func函数名(参数列表)(返回值列表){// 函数体}// 示例funcadd(xint,yint)int{returnx+y}// 简化参数类型(相同类型)funcmultiply(x,yint)int{returnx*y}

1.2 多返回值

// 返回多个值funcswap(x,ystring)(string,string){returny,x}// 命名返回值funcsplit(sumint)(x,yint){x=sum*4/9y=sum-xreturn// 裸返回,自动返回x和y}

二、函数类型与高级特性

2.1 函数作为值

funcmain(){// 函数赋值给变量add:=func(x,yint)int{returnx+y}fmt.Println(add(3,4))// 7// 函数作为参数calculate:=func(fnfunc(int,int)int,a,bint)int{returnfn(a,b)}result:=calculate(add,5,3)fmt.Println(result)// 8}

2.2 闭包

// 返回函数的函数funcadder()func(int)int{sum:=0returnfunc(xint)int{sum+=xreturnsum}}funcmain(){pos,neg:=adder(),adder()fori:=0;i<10;i++{fmt.Println(pos(i),// 0, 1, 3, 6, 10...neg(-2*i),// 0, -2, -6, -12...)}}

2.3 可变参数

// ... 表示可变参数funcsum(numbers...int)int{total:=0for_,num:=rangenumbers{total+=num}returntotal}funcmain(){fmt.Println(sum(1,2,3))// 6fmt.Println(sum(1,2,3,4,5))// 15// 切片作为可变参数nums:=[]int{1,2,3,4}fmt.Println(sum(nums...))// 10}

三、方法与接收者

3.1 方法定义

typeRectanglestruct{width,heightfloat64}// 值接收者func(r Rectangle)area()float64{returnr.width*r.height}// 指针接收者(可以修改结构体)func(r*Rectangle)scale(factorfloat64){r.width*=factor r.height*=factor}funcmain(){rect:=Rectangle{width:3,height:4}fmt.Println(rect.area())// 12rect.scale(2)fmt.Println(rect.width,rect.height)// 6 8}

3.2 接收者选择

typeCounterstruct{valueint}// 值接收者:不修改原对象,适用于小型结构体func(c Counter)GetValue()int{returnc.value}// 指针接收者:需要修改对象或避免复制大对象func(c*Counter)Increment(){c.value++}// 指针接收者:确保一致性(推荐)func(c*Counter)Decrement(){c.value--}

四、函数高级特性

4.1 延迟执行(defer)

funcprocessFile(filenamestring)error{file,err:=os.Open(filename)iferr!=nil{returnerr}deferfile.Close()// 确保文件被关闭// 多个defer按LIFO顺序执行deferfmt.Println("文件处理完成")deferfmt.Println("清理临时资源")// 处理文件...returnnil}

4.2 匿名函数

funcmain(){// 立即执行函数func(){fmt.Println("立即执行")}()// 延迟执行的匿名函数deferfunc(){fmt.Println("延迟执行")}()// 作为回调nums:=[]int{1,2,3,4}squares:=make([]int,len(nums))fori,v:=rangenums{func(xint){squares[i]=x*x}(v)}fmt.Println(squares)// [1 4 9 16]}

4.3 错误处理函数

// 返回错误的函数funcdivide(a,bfloat64)(float64,error){ifb==0{return0,errors.New("除数不能为零")}returna/b,nil}// 带错误处理的辅助函数funcmustDivide(a,bfloat64)float64{result,err:=divide(a,b)iferr!=nil{panic(err)}returnresult}

五、接口与函数

5.1 函数类型实现接口

typeHandlerfunc(string)string// 为函数类型添加方法func(h Handler)Process(sstring)string{returnh(s)}// 函数作为接口实现typeStringProcessorinterface{Process(string)string}funcmain(){varprocessor StringProcessor// 函数转换为Handler类型upper:=Handler(strings.ToUpper)processor=upper fmt.Println(processor.Process("hello"))// HELLO}

5.2 回调函数模式

typeFilterFuncfunc(int)boolfuncfilter(numbers[]int,fn FilterFunc)[]int{varresult[]intfor_,n:=rangenumbers{iffn(n){result=append(result,n)}}returnresult}funcmain(){numbers:=[]int{1,2,3,4,5,6,7,8,9}// 偶数筛选even:=filter(numbers,func(nint)bool{returnn%2==0})// 大于5筛选large:=filter(numbers,func(nint)bool{returnn>5})fmt.Println(even)// [2 4 6 8]fmt.Println(large)// [6 7 8 9]}

六、最佳实践与模式

6.1 函数选项模式

typeServerstruct{hoststringportinttimeout time.Duration}typeOptionfunc(*Server)funcWithHost(hoststring)Option{returnfunc(s*Server){s.host=host}}funcWithPort(portint)Option{returnfunc(s*Server){s.port=port}}funcWithTimeout(timeout time.Duration)Option{returnfunc(s*Server){s.timeout=timeout}}funcNewServer(opts...Option)*Server{s:=&Server{host:"localhost",port:8080,timeout:30*time.Second,}for_,opt:=rangeopts{opt(s)}returns}funcmain(){// 使用选项模式server:=NewServer(WithHost("127.0.0.1"),WithPort(9000),WithTimeout(60*time.Second),)}

6.2 中间件模式

typeMiddlewarefunc(http.HandlerFunc)http.HandlerFuncfunclogging(next http.HandlerFunc)http.HandlerFunc{returnfunc(w http.ResponseWriter,r*http.Request){start:=time.Now()next(w,r)fmt.Printf("请求处理耗时: %v\n",time.Since(start))}}funcauth(next http.HandlerFunc)http.HandlerFunc{returnfunc(w http.ResponseWriter,r*http.Request){token:=r.Header.Get("Authorization")iftoken==""{http.Error(w,"未授权",http.StatusUnauthorized)return}next(w,r)}}// 组合中间件funcchain(middlewares...Middleware)Middleware{returnfunc(next http.HandlerFunc)http.HandlerFunc{fori:=len(middlewares)-1;i>=0;i--{next=middlewares[i](next)}returnnext}}

七、性能考虑

7.1 内联优化

// 小函数会被编译器内联funcadd(a,bint)int{returna+b}// 避免复杂函数影响内联funccomplexCalculation(x,yint)int{// 复杂逻辑...returnresult}

7.2 内存分配

// 避免在热路径中分配内存funcprocess(data[]byte){// 复用缓冲区varbuf[1024]byte// ... 处理逻辑}// 使用sync.Pool重用对象varbufferPool=sync.Pool{New:func()interface{}{returnmake([]byte,0,1024)},}

总结要点

  1. 函数设计原则

    • 保持函数简短(建议不超过50行)
    • 单一职责原则
    • 良好的命名和文档
  2. 错误处理

    • 使用多返回值处理错误
    • 尽早返回错误
    • 提供上下文信息
  3. 性能考虑

    • 小函数有利于内联
    • 避免不必要的内存分配
    • 合理使用指针接收者
  4. 代码组织

    • 相关函数分组
    • 使用接口抽象行为
    • 遵循Go惯用模式
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/24 14:21:55

抖音批量下载终极指南:开源工具高效使用手册

抖音批量下载终极指南&#xff1a;开源工具高效使用手册 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 还在为保存喜欢的抖音视频而烦恼吗&#xff1f;手动下载、去水印、整理文件&#xff0c;这些重复性工…

作者头像 李华
网站建设 2026/8/23 23:06:17

Wan2.2-T2V-A14B模型生成视频的元数据嵌入与追踪

Wan2.2-T2V-A14B模型生成视频的元数据嵌入与追踪 在AI生成内容&#xff08;AIGC&#xff09;飞速普及的今天&#xff0c;一段由“宇航员漫步火星”这样一句话生成的高清视频&#xff0c;可能只需几十秒就能完成。但随之而来的问题也愈发尖锐&#xff1a;这段视频是谁生成的&…

作者头像 李华
网站建设 2026/8/24 14:13:03

Mendeley文献管理 数量太多更新太慢

最后一次更新时可以新建一个文档&#xff0c;把参考文献很多的那部分一点一点的复制到新文档中&#xff0c;这样每一部分就可以很快的更新完成。

作者头像 李华
网站建设 2026/8/24 14:59:35

7步掌握dotfiles配置管理:打造你的专属Linux桌面环境

7步掌握dotfiles配置管理&#xff1a;打造你的专属Linux桌面环境 【免费下载链接】dotfiles The ML4W Dotfiles for Hyprland - An advanced and full-featured configuration for the dynamic tiling window manager Hyprland including an easy to use installation script f…

作者头像 李华
网站建设 2026/8/24 14:37:55

别再手动重启Agent了!自动化治理的5个黄金实践法则

第一章&#xff1a;云原生Agent服务治理的演进与挑战 随着微服务架构在云原生环境中的广泛应用&#xff0c;Agent模式逐渐成为服务治理的关键组件。传统中间件能力被下沉至轻量级运行时代理中&#xff0c;实现对流量控制、安全认证、可观测性等治理功能的统一管理。这一演进显著…

作者头像 李华