前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >三分钟学 Go 语言——函数深度解析(下) 可变参数

三分钟学 Go 语言——函数深度解析(下) 可变参数

作者头像
机智的程序员小熊
发布2020-05-12 15:00:22
6390
发布2020-05-12 15:00:22
举报

接连两篇函数专题深度解析,相信大家已经对函数的语法有了深入的了解。

  • 函数简单使用和基本知识解析
  • 匿名函数和闭包

五一放假期间,我懂得,估计你们都不想学习。

小熊这两天因为个人种种令人难受的原因,没有能更新,也没有提前请假,给大家道歉歉了。

这次小熊给大家带来了一个函数的特性【可变参数】,作为函数专题的结束。

有没有发现?

我们有时候会用到的输出、错误输出、字符串格式化系统函数,你可以传入任意个数的参数,他全都能处理!

fmt.Println("a","b","c","d")

就像一个任劳任怨的老父亲,那到底是为什么呢?

因为

因为在go语言中语言级别自带了一种语法,可以声明可变参数!

func 函数名(固定参数,v ...T) (返回参数列表){
函数体
}
怎么用?

先和小熊一起试试,写一个不定参数累加的函数

func sum(t ...int) (res int) {
 for _, v := range t {
  res += v
 }
 return res
}
fmt.Println(sum(1, 2, 3, 4, 5))

输出结果

15
如果连参数类型都不知道,怎么办?

上一节我们已知参数类型是int,还记得我们前面说过的switch判断类型做处理的例子吗?switch和type switch

参考这个例子重写下函数,让他可以接收任意类型的参数。


func sumNum(t ...interface{}) (res float64){
 for _,tmp := range t{
  switch v :=tmp.(type) {
  case int:
   res += float64(v)
  case float64:
   res+= v
  case float32:
   res += float64(v)
  }
 }
 return res
}

测试下

fmt.Println(sumNum(1,2.1,"asd",true))

因为忽略了输出

3.1

但是上面的例子并没有覆盖全部的数字,如果一个一个类型的匹配会疯掉的。有没有更好的方法,可以一下子匹配到所有的数字?


func sumNum(t ...interface{}) (res float64) {
 for _, tmp := range t {
  switch v := tmp.(type) {
  case int, int8, int16, 
    int32, int64, uint, 
    uint8, uint16, uint32,
    uint64, float32, float64, 
    complex64, complex128:
   convertStr := fmt.Sprintf("%v", v)
   convertFloat64, _ := strconv.ParseFloat(convertStr, 64)
   res += convertFloat64
  }
 }
 return res
}

上面的代码在case里一下子匹配了所有可能的数字类型,再用格式化输出转换成字符串,最后转换成float64来使用,这是一种折中的办法,速度可能会比较慢(因为格式化内部逻辑比较复杂消耗速度)。

为了保证速度还是不要省掉一大堆的case,明确了类型再做强转。

留给你的寻找的答案

有没有一种只留一个case,同时处理速度又快的方法呢?

—— 爱你们的小熊

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机智的程序员小熊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 有没有发现?
  • 因为
  • 怎么用?
  • 如果连参数类型都不知道,怎么办?
  • 留给你的寻找的答案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档