GO 语言如何用好变长参数?

简介: GO 语言如何用好变长参数?

函数重载

对于函数重载相信编码过的 xdm 肯定不会陌生,函数重载就是在同一个作用域内定义多个具有相同名称但参数列表不同的函数

此处的参数列表不同,可以是参数的类型不同,参数的个数不同

那么我们一起分别来看看 C 语言,C++ 语言,GO 语言 如何去模拟和使用重载,体会一下

C语言模拟重载

那么我们以前学过的 C 语言,是不支持重载的,是不会自动根据参数类型来进行匹配的,但是我们可以通过一些技巧来模拟函数重载,例如我们可以定义一类名字相似的函数,参数列表来模拟重载的效果

例如:

  1. 定义函数 sum_int ,参数为 2 个 int 类型的变量
  2. 定义函数 sum_double ,参数为 2 个 double 类型的变量
  3. 定义函数 sum_float ,参数为 2 个 float 类型的变量
int sum_int(int x, int y) {
    return x + y;
}
double sum_int(double x, double y) {
    return x + y;
}
float sum_int(float x, float y) {
    return x + y;
}

那么在调用的时候,我们就会根据不同的入参类型来调用对应的函数

C++ 重载

又如我们写 C++ 的时候,这个语言是支持重载的,我们可以在调用函数的时候,传入不同的参数类型,不同的参数个数来决定我们需要调用哪个函数的具体实现,我们来看看如何来使用重载

例如:

  1. 定义一个函数 getinfo ,参数为 int 类型的变量
  2. 还是 getinfo 函数,参数为 double 类型的变量
  3. 还是 getinfo 函数,参数为 string 类型的变量
void getinfo (int x) {
    std::cout << "int 类型入参: " << x << std::endl;
}
void getinfo (double x) {
    std::cout << "double 类型入参: " << x << std::endl;
}
void getinfo (std::string x) {
    std::cout << "std::string 类型入参: " << x << std::endl;
}

使用 C++ 的时候,我们可以看到,使用同一个函数,咱们直接就可以传入不同类型的入参,来应用重载

GO语言模拟重载

那么,GO 语言本身也是不允许重载的,因为GO语言的设计理念就是简洁和易读,这样可以避免代码的复杂和可维护性

不过我们在使用的时候,为了我们实现我们不同的业务场景,可以使用GO 语言中的变长参数来进行模拟

例如:

  1. 定义一个函数 overloadTest,参数为一个变长参数,参数类型为 …interface{}
  2. 那么,对于这个函数,我们参数个数和参数类型,都可以按照我们的需求进行传递即可
func overloadTest(name string, hobby ...interface{}){
    for _,v :=range hobby {
       switch v.(type) {
       case int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64:
         fmt.Printf("%s love 整数  -- %+v \n",name, v)
       case string:
          fmt.Printf("%s love 字符串 -- %+v \n",name, v)
       case []int:
         tmpInts := v.([]int)
          fmt.Printf("%s love 整型切片 -- %+v \n",name, tmpInts)
       default:
          fmt.Printf("%s  not love type  -- %+v \n",name, v)
       }
    }
}
func main(){
   overloadTest("xiaozhu", "learning", "playing")
   overloadTest("xiaozhu", []int{1,2,3,4})
   overloadTest("xiaozhu", map[string]int{"apple":2000})
   overloadTest("xiaozhu", 100)
}

可以看到 GO 语言公共库中使用变长参数的地方还是非常多的,例如打印相关的

fmt 包中的 Printf

fmt 包中的 Println

还有我们使用切片时经常使用的 append 函数

使用变长参数的的场景还是不少的,可以多留意咱们的公共库,用起来也是非常的方便,我们需要对变长参数的设计和实现要有更多的理解,用起来才能够得心应手

GO 语言中的变长参数

对于 GO 语言中的变长参数定义为:函数调用时指可以接受 0 个,1 个或者多个实际参数的函数

此处的定义,是否看上去和重载的定义稍微相似呢?

例如上述的 GO 语言的demo,给函数中传入变长参数的时候,我们就是在参数列表中写入 ...T ,那么很明显,一个函数中只能有一个这样的边长参数,且这个参数需要放到参数列表的最后一个

否则 GO 语言就不知道你传入的哪一些参数是属于变长参数的入参值了,xdm 们可以思考一下,如果这个变长参数放到参数列表的开头,或者参数列表的中间,那么我们在传递参数的时候,如何去识别呢?

我们可以来实际演示一波:

  1. 定义一个函数,变长参数列表类型为 string,且放到参数列表最后
  2. 同样的函数,将变长参数列表放到第一个
  3. 同样的函数,将变长参数列表放到第二个

这里实际上可以看到,变长参数的本质实际上就是一个切片类型的实例,函数内部实现,就是将这个参数作为切片来进行处理的,这也得益于切片的长度不是固定的

这里需要注意的一点:

函数定义了变长参数,我们在传递的时候可以一个一个的传,也可以使用切片变量后加… 的方式来传递,但是这两种传递方式不能混合使用,只能取其一

如何实现参数可选和默认参数呢?

思考一下,变长参数我们知道如何使用了,如何实现默认参数和可选参数呢?

实际上就是咱们在实现的时候,在函数内部控制我们需要必须传递的可选参数(实际是切片类型)最小的长度,或者最大的长度,然后去读取相应位置的值即可

这一点 xdm 感兴趣的可以参考上述 GO 语言demo 来实现一下默认参数和可选参数哦,通过去校验变长参数的长度,数据类型就可以做到这一点,可以在评论区留下的 demo 哦

还记得 grpc 中的功能选项模式吗?

在 GO 语言中,微服务的开发相信我们使用的不会少,那么在使用 grpc 通信的时候,我们就可以发现处理 rpc 接口的时候,我们是可以传递拦截器的,这个参数,就是功能选项模式

我们可以仿照它弄一个我们自己的功能选项模式:

现在汽车打价格战,疯狂的卖车,我们就用给车加选装来作为例子来体验选项模式的实现:

  1. 定义一台车,属性有颜色,座椅,品牌,风格,能源 其中部分配置是选装,也可以不选
type ABINGCar struct{
   Brand string
   Style string
   MarshmallowChair int   // 棉花糖座椅
   Color string
   Power string
}
  1. 给选装的配置,写好对应的选项功能
type Option func(*ABINGCar)
func WithStyle(style string)Option{
   return func(a *ABINGCar){
      a.Style = style
   }
}
func WithMarshmallowChair(enable int)Option{
   return func(a *ABINGCar){
      a.MarshmallowChair = enable
   }
}
func WithPower(power string)Option{
   return func(a *ABINGCar){
      a.Power = power
   }
}
  1. New 一台车出来,写一个 NewCar,加上选项功能
func NewCar(options ...Option) *ABINGCar{
   car := &ABINGCar{
      Color: "red",
      Brand: "abing brand",
   }
   for _,option := range options{
      option(car)
   }
   return  car
}
  1. 在 main 函数中,去买车,买不同的车,可以选装不同的配置,想咋选咋选

总结

本次主要分享了不同语言的重载和模拟重载的效果,GO 语言中如何用好边长参数,如何实现 选项功能模式,希望对你有点帮助

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI

相关文章
|
14天前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
|
15天前
|
编译器 Go
揭秘 Go 语言中空结构体的强大用法
Go 语言中的空结构体 `struct{}` 不包含任何字段,不占用内存空间。它在实际编程中有多种典型用法:1) 结合 map 实现集合(set)类型;2) 与 channel 搭配用于信号通知;3) 申请超大容量的 Slice 和 Array 以节省内存;4) 作为接口实现时明确表示不关注值。此外,需要注意的是,空结构体作为字段时可能会因内存对齐原因占用额外空间。建议将空结构体放在外层结构体的第一个字段以优化内存使用。
|
20天前
|
存储 Go
Go 语言入门指南:切片
Golang中的切片(Slice)是基于数组的动态序列,支持变长操作。它由指针、长度和容量三部分组成,底层引用一个连续的数组片段。切片提供灵活的增减元素功能,语法形式为`[]T`,其中T为元素类型。相比固定长度的数组,切片更常用,允许动态调整大小,并且多个切片可以共享同一底层数组。通过内置的`make`函数可创建指定长度和容量的切片。需要注意的是,切片不能直接比较,只能与`nil`比较,且空切片的长度为0。
Go 语言入门指南:切片
|
19天前
|
开发框架 前端开发 Go
eino — 基于go语言的大模型应用开发框架(二)
本文介绍了如何使用Eino框架实现一个基本的LLM(大语言模型)应用。Eino中的`ChatModel`接口提供了与不同大模型服务(如OpenAI、Ollama等)交互的统一方式,支持生成完整响应、流式响应和绑定工具等功能。`Generate`方法用于生成完整的模型响应,`Stream`方法以流式方式返回结果,`BindTools`方法为模型绑定工具。此外,还介绍了通过`Option`模式配置模型参数及模板功能,支持基于前端和用户自定义的角色及Prompt。目前主要聚焦于`ChatModel`的`Generate`方法,后续将继续深入学习。
167 7
|
15天前
|
存储 缓存 监控
企业监控软件中 Go 语言哈希表算法的应用研究与分析
在数字化时代,企业监控软件对企业的稳定运营至关重要。哈希表(散列表)作为高效的数据结构,广泛应用于企业监控中,如设备状态管理、数据分类和缓存机制。Go 语言中的 map 实现了哈希表,能快速处理海量监控数据,确保实时准确反映设备状态,提升系统性能,助力企业实现智能化管理。
29 3
|
15天前
|
存储 缓存 安全
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
|
20天前
|
存储 开发框架 Devops
eino — 基于go语言的大模型应用开发框架(一)
Eino 是一个受开源社区优秀LLM应用开发框架(如LangChain和LlamaIndex)启发的Go语言框架,强调简洁性、可扩展性和可靠性。它提供了易于复用的组件、强大的编排框架、简洁明了的API、最佳实践集合及实用的DevOps工具,支持快速构建和部署LLM应用。Eino不仅兼容多种模型库(如OpenAI、Ollama、Ark),还提供详细的官方文档和活跃的社区支持,便于开发者上手使用。
125 8
|
20天前
|
存储 算法 Go
Go语言实战:错误处理和panic_recover之自定义错误类型
本文深入探讨了Go语言中的错误处理和panic/recover机制,涵盖错误处理的基本概念、自定义错误类型的定义、panic和recover的工作原理及应用场景。通过具体代码示例介绍了如何定义自定义错误类型、检查和处理错误值,并使用panic和recover处理运行时错误。文章还讨论了错误处理在实际开发中的应用,如网络编程、文件操作和并发编程,并推荐了一些学习资源。最后展望了未来Go语言在错误处理方面的优化方向。
|
16天前
|
SQL 安全 Java
阿里双十一背后的Go语言实践:百万QPS网关的设计与实现
解析阿里核心网关如何利用Go协程池、RingBuffer、零拷贝技术支撑亿级流量。 重点分享: ① 如何用gRPC拦截器实现熔断限流; ② Sync.Map在高并发读写中的取舍。
|
17天前
|
存储 算法 安全
基于 Go 语言的公司内网管理软件哈希表算法深度解析与研究
在数字化办公中,公司内网管理软件通过哈希表算法保障信息安全与高效管理。哈希表基于键值对存储和查找,如用户登录验证、设备信息管理和文件权限控制等场景,Go语言实现的哈希表能快速验证用户信息,提升管理效率,确保网络稳定运行。
27 0