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

Go05-函数与方法

第4章:函数与方法

4.1 函数基础

函数声明

// 基本语法func函数名(参数列表)返回值列表{// 函数体}// 示例funcadd(aint,bint)int{returna+b}// 简写参数类型(相同类型)funcadd(a,bint)int{returna+b}

多返回值

// Go 函数支持多返回值funcdivide(a,bfloat64)(float64,error){ifb==0{return0,errors.New("除数不能为零")}returna/b,nil}// 使用result,err:=divide(10,3)iferr!=nil{fmt.Println("错误:",err)}else{fmt.Println("结果:",result)}

命名返回值

// 命名返回值相当于在函数内部声明变量funcswap(a,bint)(x,yint){x=b y=areturn// 裸返回,自动返回命名返回值}// 使用x,y:=swap(1,2)fmt.Println(x,y)// 输出:2 1

4.2 函数作为值

Go 中函数是一等公民,可以赋值给变量、作为参数传递:

// 函数作为变量add:=func(a,bint)int{returna+b}fmt.Println(add(1,2))// 输出:3// 函数作为参数funcapply(a,bint,operationfunc(int,int)int)int{returnoperation(a,b)}result:=apply(10,5,func(a,bint)int{returna-b})fmt.Println(result)// 输出:5// 函数作为返回值funccreateMultiplier(factorint)func(int)int{returnfunc(xint)int{returnx*factor}}double:=createMultiplier(2)fmt.Println(double(5))// 输出:10

4.3 闭包

闭包是引用了外部变量的函数:

// 闭包示例:计数器funccounter()func()int{count:=0returnfunc()int{count++returncount}}c:=counter()fmt.Println(c())// 1fmt.Println(c())// 2fmt.Println(c())// 3// 闭包示例:函数工厂funcgreet(prefixstring)func(string)string{returnfunc(namestring)string{returnprefix+", "+name+"!"}}hello:=greet("你好")goodbye:=greet("再见")fmt.Println(hello("张三"))// 你好, 张三!fmt.Println(goodbye("李四"))// 再见, 李四!

4.4 可变参数

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

4.5 方法

方法是带有接收者的函数:

// 定义结构体typeRectanglestruct{Width,Heightfloat64}// 值接收者方法func(r Rectangle)Area()float64{returnr.Width*r.Height}// 指针接收者方法(可以修改接收者)func(r*Rectangle)Scale(factorfloat64){r.Width*=factor r.Height*=factor}// 使用rect:=Rectangle{Width:10,Height:5}fmt.Println("面积:",rect.Area())// 50rect.Scale(2)fmt.Println("缩放后面积:",rect.Area())// 200

值接收者 vs 指针接收者

typeCounterstruct{Valueint}// 值接收者:操作副本,不影响原值func(c Counter)Increment(){c.Value++// 修改的是副本}// 指针接收者:操作原值func(c*Counter)Increment(){c.Value++// 修改的是原值}// 选择原则:// 1. 如果需要修改接收者,使用指针接收者// 2. 如果接收者是大型结构体,使用指针接收者(避免复制)// 3. 一致性:同一类型的方法应使用相同的接收者类型

4.6 内置函数

Go 提供了一些内置函数:

// len - 获取长度s:="Hello"fmt.Println(len(s))// 5// cap - 获取容量slice:=make([]int,5,10)fmt.Println(cap(slice))// 10// make - 创建切片、map、channelslice:=make([]int,5)// 长度为5的切片m:=make(map[string]int)// 空mapch:=make(chanint,100)// 带缓冲的channel// new - 分配内存,返回指针p:=new(int)// *int 类型*p=42fmt.Println(*p)// 42// copy - 复制切片src:=[]int{1,2,3}dst:=make([]int,len(src))copy(dst,src)// delete - 删除map元素m:=map[string]int{"a":1,"b":2}delete(m,"a")// panic - 触发恐慌// recover - 捕获恐慌

4.7 练习

  1. 编写函数计算斐波那契数列
  2. 实现一个函数工厂,根据参数返回不同的排序函数
  3. 使用闭包实现一个简单的缓存
  4. 为自定义类型实现 Stringer 接口

4.8 下一章

下一章我们将学习 Go 语言的数组、切片与 Map。

http://www.cnnetsun.cn/news/3438297.html

相关文章:

  • 栈的C/C++实现:从数组到链表的三种经典结构
  • 如何应用 -中国多时期土地利用数据 CNLUCC|1980-2025|1km全国土地利用/土地覆盖栅格数据
  • 公考培训AI大模型横评:三家头部机构的技术底色差异有多大
  • 电解电容选型五大核心参数与工程实践
  • 小白程序员必看!收藏这份RAG技术指南,轻松玩转大模型知识增强检索
  • 突破分布式游戏服务器通信瓶颈:ET框架Actor模型的深度架构设计与性能优化实践
  • Phaser框架终极指南:3分钟快速掌握HTML5游戏开发
  • Ascend C关键分形格式详解
  • 图解软件开发:从需求到实现的四大核心建模图(用例图、类图、时序图、ER图)
  • 2026 国产 ** 制造 EDA(晶圆工艺 EDA)产业现状 + 企业人才缺口深度解析
  • Jenkins参数化构建Unity多平台自动化打包实战指南
  • 多租户SaaS架构下的BI数据隔离与权限治理体系
  • 3步终极指南:让老旧Mac免费升级到最新macOS系统的完整方案
  • yuque-hexo常见问题解答:解决同步过程中的9大痛点
  • codes外网访问实战:frp穿透8091端口与HTTPS全链路部署
  • pass-js API参考:模板、通行证与字段操作的10个实用方法
  • CANN/Ascend C SIMD浮点转整型
  • 【单片机毕业设计】基于 STM32 的带温度补偿超声波测距报警系统设计,基于 STM32 单片机的可调阈值超声波防撞预警装置开发(014202)
  • 【单片机毕业设计】基于 STM32/51 单片机的公交 GPS 自动语音报站系统设计与实现,基于 STM32/51 单片机的车载手动与自动双模语音报站装置设计(014602)
  • JAMstack CMS核心功能解析:认证授权、数据库与动态管理面板全攻略
  • 头歌 实战入门 - 分布式版本控制核心操作
  • 传感器核心参数实战解析:从理论带宽到工程精度
  • Deep-Live-Cam终极指南:3步实现专业级实时AI换脸
  • 从零构建节假日数据服务:ThinkAPI集成与本地化存储实践
  • 从零到一:我的单周期CPU设计实战与Verilog实现
  • Wan2.2-TI2V-5B:如何在消费级GPU上运行720P专业视频生成
  • AI 辅助 Rust 架构评审:让模型扮演不同角色交叉验证你的设计
  • 基于SSM医院电子病历管理系统的设计与实现
  • LCD显示屏
  • AT89C51定时器实战:从方波到PWM脉冲的三种经典信号生成方案