Go语言怎么使用变长参数函数


Posted in Golang onJuly 15, 2022

本文我们主要介绍在 Go 语言中怎么使用变长参数函数,先是介绍变长参数和变长参数函数的相关知识,然后列举了一个简单示例,通过示例代码,加深读者朋友们的理解。

01 介绍

Go 语言中函数的最后一个参数可以是变长参数,细心的读者朋友们可能已经发现,在 Go 语言标准库 fmt​包中就有使用变长参数函数,比如 Println​ 和 Printf。

我们在使用 Go 语言开发应用程序时,也可以在合适的场景使用变长参数函数,使我们的代码更优雅。

02 变长参数

顾名思义,变长参数是指参数的数量不固定,可以是 0 个,1 个或多个。变长参数的格式是 ...T​,在参数的类型前面有 3 个 .,表示该参数是变长参数。

变长参数在函数体内是切片类型的参数,也就是说 ...T​ 等价于 []T。

变长参数在函数外部可匹配的参数类型有两种,分别是一个 []T​ 切片类型的变量,和多个 T 类型的变量,并且二者不可以同时使用,也就是说它们不能同时出现在函数的参数列表中。

03 变长参数函数

我们已经知道什么是变长参数,自然我们也就可以想到接受 ...T 形式的形参的函数就是变长参数函数。

一个变长参数函数只能有一个 ...T 形式的形参,并且该形参必须是函数参数列表中的最后一个形参。

需要注意的是,变长参数函数最容易踩的“坑”就是形参和实参的类型不匹配,例如以下这段代码:

func sum(args ...interface{}) {
    res := 0
    for _, v := range args {
        res += v.(int)
    }
    fmt.Println(res)
}

func main() {
    num := []int{1, 2, 3}
    sum(num...)
}

输出结果:

./prog.go:18:6: cannot use num (variable of type []int) as type []interface{} in argument to sum

阅读上面这段代码,我们发现程序运行错误的原因是实参类型和形参类型不一致,导致编译错误。可能有读者朋友们感到疑惑,int​ 类型的变量可以直接赋值给 interface{} 类型的变量,为什么会报错呢?

这是因为实参的类型是 []int​,它不能匹配形参 []interface{}​。修改该错误也简单,只需将实参的类型修改为 []interface{}。

num := []interface{}{1, 2, 3}

04 使用场景

我们了解完变长参数和变长参数函数,再通过一个示例代码加深一下读者朋友们的理解。

该使用场景是通过调用下游方法,输入用户的个人资料。但是,后期调用的下游方法的入参发生变化,新增了一个或多个请求参数。

如果不使用变长参数,我们原来调用该下游方法的代码都需要随之修改。以下是示例代码:

变更前的示例代码:

func CallUserCenter(name string, age int, gender string) (detail *User, err error) {
 detail, err = NewUserUsecase().Create(name, age, gender)
 if err != nil {
  return
 }
 return
}

变更后的示例代码:

func CallUserCenter(name string, age int, gender string, args ...interface{}) (detail *User, err error) {
 if len(args) == 0 {
  detail, err = NewUserUsecase().Create(name, age, gender)
 } else {
  detail, err = NewUserUsecase().Create(name, age, gender, args[0])
 }
 if err != nil {
  return
 }
 return
}

调用函数的示例代码:

func main() {
 name := "frank"
 age := 18
 gender := "male"
 detail, err := CallUserCenter(name, age, gender)
 if err != nil {
  fmt.Printf("err=%v\n", err)
  return
 }
 fmt.Printf("name:%s\nage:%d\ngender:%s\n", detail.name, detail.age, detail.gender)
 fmt.Printf("%s\n", "********************")
 name2 := "lucy"
 age2 := 17
 gender2 := "female"
 salary2 := 5000

 detail2, err := CallUserCenter(name2, age2, gender2, salary2)
 if err != nil {
  fmt.Printf("err=%v\n", err)
  return
 }
 fmt.Printf("name:%s\nage:%d\ngender:%s\nsalary:%d\n", detail2.name, detail2.age, detail2.gender, detail2.salary)
}

阅读上面这段代码,因为我们使用变长参数的形式,修改调用的下游函数的入参,也就是将原来调用的下游函数由普通函数改为变长参数函数。

通过该方式变更代码,不仅实现了函数的预期功能,还不会入侵之前的调用代码。限于篇幅,示例完整代码请查阅 Github

05 总结

本文我们主要介绍在 Go 语言中怎么使用变长参数函数,先是介绍变长参数和变长参数函数的相关知识,然后列举了一个简单示例,通过示例代码,加深读者朋友们的理解。

到此这篇关于Go 语言怎么使用变长参数函数的文章就介绍到这了,更多相关Go 变长参数函数内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Golang 相关文章推荐
golang通过递归遍历生成树状结构的操作
Apr 28 Golang
golang 实现菜单树的生成方式
Apr 28 Golang
Golang中interface{}转为数组的操作
Apr 30 Golang
golang协程池模拟实现群发邮件功能
May 02 Golang
Go 自定义package包设置与导入操作
May 06 Golang
go mod 安装依赖 unkown revision问题的解决方案
May 06 Golang
试了下Golang实现try catch的方法
Jul 01 Golang
go开发alertmanger实现钉钉报警
Jul 16 Golang
golang生成vcf通讯录格式文件详情
Mar 25 Golang
golang三种设计模式之简单工厂、方法工厂和抽象工厂
Apr 10 Golang
Golang bufio详细讲解
Apr 21 Golang
深入理解 Golang 的字符串
May 04 Golang
Go微服务项目配置文件的定义和读取示例详解
Jun 21 #Golang
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
Jun 21 #Golang
Go 内联优化让程序员爱不释手
Jun 21 #Golang
GoFrame框架数据校验之校验结果Error接口对象
Jun 21 #Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 #Golang
Golang gRPC HTTP协议转换示例
Go Grpc Gateway兼容HTTP协议文档自动生成网关
Jun 16 #Golang
You might like
ThinkPHP结合AjaxFileUploader实现无刷新文件上传的方法
2014/10/29 PHP
浅谈laravel框架sql中groupBy之后排序的问题
2019/10/17 PHP
JavaScript 未结束的字符串常量常见解决方法
2010/01/24 Javascript
Jsonp 跨域的原理以及Jquery的解决方案
2010/05/18 Javascript
基于jQuery的的一个隔行变色,鼠标移动变色的小插件
2010/07/06 Javascript
删除条目时弹出的确认对话框
2014/06/05 Javascript
dedecms页面如何获取会员状态的实例代码
2016/03/15 Javascript
基于socket.io+express实现多房间聊天
2016/03/17 Javascript
jQuery文字提示与图片提示效果实现方法
2016/07/04 Javascript
JavaScript类的写法
2016/09/17 Javascript
Angular2-primeNG文件上传模块FileUpload使用详解
2017/01/14 Javascript
jQuery为DOM动态追加事件的方法
2017/02/16 Javascript
详解JS中的立即执行函数
2017/02/24 Javascript
20行JS代码实现网页刮刮乐效果
2017/06/23 Javascript
JS实现中文汉字按拼音排序的方法
2017/10/09 Javascript
关于redux-saga中take使用方法详解
2018/02/27 Javascript
了解前端理论:rscss和rsjs
2019/05/23 Javascript
[46:09]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第三场
2014/05/26 DOTA
[03:55]2014DOTA2国际邀请赛 Fnatic经理采访赢DK在情理之中
2014/07/10 DOTA
python实现汉诺塔递归算法经典案例
2021/03/01 Python
Linux上安装Python的PIL和Pillow库处理图片的实例教程
2016/06/23 Python
python 类详解及简单实例
2017/03/24 Python
Python之inspect模块实现获取加载模块路径的方法
2018/10/16 Python
Python文件打开方式实例详解【a、a+、r+、w+区别】
2019/03/30 Python
python求一个字符串的所有排列的实现方法
2020/02/04 Python
python3实现名片管理系统(控制台版)
2020/11/29 Python
Python 图片处理库exifread详解
2021/02/25 Python
Html5实现二维码扫描并解析
2016/01/20 HTML / CSS
TripAdvisor斯洛伐克:阅读评论、比较价格和酒店预订
2018/04/25 全球购物
澳大利亚婴儿礼品公司:The Baby Gift Company
2018/11/04 全球购物
入党申请人的自我鉴定
2013/12/01 职场文书
大学新生军训感言
2014/02/25 职场文书
淘宝客服工作职责
2014/07/11 职场文书
县委常委班子对照检查材料思想汇报
2014/09/28 职场文书
2016年社区六一儿童节活动总结
2016/04/06 职场文书
新手入门Jvm-- JVM对象创建与内存分配机制
2021/06/18 Java/Android