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 相关文章推荐
基于Go Int转string几种方式性能测试
Apr 28 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
golang 比较浮点数的大小方式
May 02 Golang
golang gopm get -g -v 无法获取第三方库的解决方案
May 05 Golang
聊聊golang中多个defer的执行顺序
May 08 Golang
go语言使用Casbin实现角色的权限控制
Jun 26 Golang
Go 语言结构实例分析
Jul 04 Golang
golang中字符串MD5生成方式总结
Jul 04 Golang
K8s部署发布Golang应用程序的实现方法
Jul 16 Golang
Go语言实现一个简单的并发聊天室的项目实战
Mar 18 Golang
如何解决goland,idea全局搜索快捷键失效问题
Apr 03 Golang
golang的文件创建及读写操作
Apr 14 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
php中的curl_multi系列函数使用例子
2014/07/29 PHP
php导出CSV抽象类实例
2014/09/24 PHP
微信利用PHP创建自定义菜单的方法
2016/08/01 PHP
PHP编程计算日期间隔天数的方法
2017/04/26 PHP
JavaScript中的面向对象介绍
2012/06/30 Javascript
解析使用JS 清空File控件的路径值
2013/07/08 Javascript
利用CSS、JavaScript及Ajax实现高效的图片预加载
2013/10/16 Javascript
上传文件返回的json数据会被提示下载问题解决方案
2014/12/03 Javascript
基于jQuery实现网页进度显示插件
2015/03/04 Javascript
jquery 全选、全不选、反选效果的实现代码【推荐】
2016/05/05 Javascript
工厂模式在JS中的实践
2017/01/18 Javascript
jQuery加密密码到cookie的实现代码
2017/04/18 jQuery
详解动画插件wow.js的使用方法
2017/09/13 Javascript
Vue header组件开发详解
2018/01/26 Javascript
理解JavaScript中的对象
2020/08/25 Javascript
python实现随机森林random forest的原理及方法
2017/12/21 Python
使用python实现链表操作
2018/01/26 Python
Anaconda2 5.2.0安装使用图文教程
2018/09/19 Python
浅谈Python中的bs4基础
2018/10/21 Python
django框架ModelForm组件用法详解
2019/12/11 Python
TensorFlow tf.nn.max_pool实现池化操作方式
2020/01/04 Python
使用python自动追踪你的快递(物流推送邮箱)
2020/03/17 Python
python写文件时覆盖原来的实例方法
2020/07/22 Python
python 下划线的不同用法
2020/10/24 Python
详解Sticky Footer 绝对底部的两种套路
2017/11/03 HTML / CSS
OPPO手机官方商城:中国手机市场出货量第一品牌
2017/10/18 全球购物
Luxplus瑞典:香水和美容护理折扣
2018/01/28 全球购物
英国灯具和灯泡网上商店:Lights.co.uk
2018/02/02 全球购物
澳大利亚男士西服品牌:M.J.Bale
2018/02/06 全球购物
Zooplus葡萄牙:欧洲领先的网上宠物商店
2018/07/01 全球购物
人事专员岗位职责
2013/11/20 职场文书
2015年新农村建设指导员工作总结
2015/07/24 职场文书
医院消毒隔离制度
2015/08/05 职场文书
apache基于端口创建虚拟主机的示例
2021/04/24 Servers
Python中基础数据类型 set集合知识点总结
2021/08/02 Python
java高级用法JNA强大的Memory和Pointer
2022/04/19 Java/Android