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

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惯用模式
http://www.jsqmd.com/news/76223/

相关文章:

  • 当“印钞机”百度开始失血,是天灾还是人祸?
  • deepseek-r1大模型的本地部署
  • 5分钟快速上手:BDD100K数据集完整下载与训练指南
  • Linux上IO性能问题的故障排除实践
  • 网站怎么实现HTTPS访问?
  • 2025年竹纤维浴巾定制厂家推荐榜单:一次性浴巾‌/超细纤维浴巾‌/纯棉浴巾源头厂家精选 - 品牌推荐官
  • C++中指针,智能指针的理解
  • MySQL:Last_IO_Errno:“0“, Last_IO_Error:““, Last_SQL_Errno:“1950“
  • 分布式应用框架Microsoft Orleans - 4、掌握Microsoft Orleans状态管理:从持久化配置到事务处理
  • 基于SSM+Vue的实习管理系统的设计与实现
  • 2025年12月铝合金母线槽,接插式母线槽,高压母线槽厂商推荐:导电效率+安装便捷度实测​ - 品牌鉴赏师
  • Wan2.2-T2V-A14B模型生成视频的元数据嵌入与追踪
  • 掌握OptiSystem的5大实战技巧:从零开始的光通信仿真指南
  • 3步掌控Mac性能:AppPolice让你的电脑告别卡顿烦恼
  • 分布式应用框架Microsoft Orleans - 2、动手实践:构建你的第一个Microsoft Orleans应用程序
  • Wan2.2-T2V-A14B能否理解‘情绪’类抽象描述?实验来了
  • 2025年质量好的隐藏式抽屉滑轨/抽屉滑轨厂家推荐及采购指南 - 行业平台推荐
  • 自动驾驶的“数据魔法师“:卡尔曼滤波如何让车辆看得更准
  • Llama-Factory训练监控系统详解:实时追踪Loss与Accuracy
  • Mirai Console Loader 终极配置指南:从零构建QQ机器人
  • 批量文本向量化革命:告别单条处理,拥抱高效AI工作流
  • 一键生成绘图仪风格线条画:Pintr终极指南
  • 享扭蛋机比较实用的功能分享
  • GLM-4.5:3550亿参数开源模型如何重新定义智能体开发范式
  • Wireshark抓包分析实战:从入门到排查网络故障
  • OpenWrt负载均衡配置实战:告别网络拥堵的多线路叠加方案
  • 2025年靠谱的橱柜缓冲滑轨实力厂家TOP推荐榜 - 品牌宣传支持者
  • 2025口碑好的停车场系统厂家TOP5权威推荐:甄选企业助力 - myqiye
  • 河北唐山市迁安市农村自建房公司深度测评,迁安市地区靠谱自建房公司实用选择指南 - 苏木2025
  • Mendeley文献管理 数量太多更新太慢