当前位置: 首页 > 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.hn-smt.com/news/91231/

相关文章:

  • Wan2.2-T2V-A14B能否理解‘情绪’类抽象描述?实验来了
  • 一键生成绘图仪风格线条画:Pintr终极指南
  • 批量文本向量化革命:告别单条处理,拥抱高效AI工作流
  • 2025年靠谱的橱柜缓冲滑轨实力厂家TOP推荐榜 - 品牌宣传支持者
  • 2025年质量好的线阵音响厂家最新权威推荐排行榜 - 行业平台推荐
  • 银行智能柜员机对话系统升级:Llama-Factory本地化部署案例
  • 全网超火台球游戏,以物理引擎打造 100% 真实体验!
  • React Stripe.js 支付集成完整教程
  • 阿里通义DeepResearch开源:30亿参数智能体重新定义AI研究范式
  • Linux 多线程进阶:不再只传 NULL —— 详解 pthread_attr_t 线程属性
  • 如何快速配置BERT模型:新手必看的完整教程
  • 漫画下载工具高效使用指南:从零构建个人漫画图书馆
  • 2025年年终滑动验证服务商推荐:技术专利、服务可用性与误判率核心维度横评 - 十大品牌推荐
  • 2025 年 4 款 AI 漫剧工具!全链路创作神器亲测对比
  • 2025 年 12 月沈阳特产老字号权威推荐榜:地道风味与新春佳礼的匠心之选 - 品牌企业推荐师(官方)
  • 2025年五大兰州口碑好资质齐全美陈设计制作专业公司排行榜, - 工业推荐榜
  • 数智化时代:AI技巧重构企业财务管理系统的底层逻辑与实践
  • 3分钟快速选择:群晖引导工具终极对比指南
  • NeurIPS‘25 | 端到端驾驶新基准!VR-Drive 新视图合成技术,路线完成率突破 92%,碾压 5 大 SOTA!
  • Open-CD变化检测终极指南:从零到精通的完整教程
  • 终极指南:快速精通Lean数学库mathlib的完整免费教程
  • TIA博途虚拟机文件完整使用指南
  • 还在手动分析CT影像?AI Agent已实现秒级病灶识别,你跟上了吗?
  • Wan2.2-T2V-A14B模型对GPU算力的需求与优化策略
  • 2025年五大知名的美缝公司推荐,有实力的美缝专业公司解析 - mypinpai
  • 天津 5 家正规大平层装饰公司,超乎你对装修的常规认知!
  • 2025年抖音矩阵工具口碑调查:谁是最佳选择?,ai数字人/企业短视频矩阵/ai和数字人/ai排行榜/ai数字人排行榜抖音矩阵系统怎么选 - 品牌推荐师
  • 2025汽车经销商AI销售企业TOP5权威推荐:智能赋能销售 - mypinpai
  • Wan2.2-T2V-A14B支持竖屏9:16比例视频输出的设置方法
  • iStoreOS路由器(openwrt软路由) AdGuard Home 客户端 IP 总是 localhost(127.0.0.1)?这样设置让你精准识别真实IP!