Golang中设置函数默认参数的优雅实现
在Golang中,我们经常碰到要设置一个函数的默认值,或者说我定义了参数值,但是又不想传递值,这个在python或php一类的语言中很好实现,但Golang中好像这种方法又不行。今天在看Grpc源码时,发现了一个方法可以很优雅的实现,叫做 Functional Options Patter.通过定义函数的方式来实现
比如我们以如下的构造函数为例说明下,用这个的好处
func NewClient(address string,timeout,trynums int){}
如果我们要实例化这个函数,timeout,trynums这个是必须要传的,那如果我不想传呢,一般可能是通过传对象(struct,map)或定义多个func,感觉都不太方便。
func NewClient(address string){}
func NewClientNoTimeout(address string,trynums int){}
另一种传一个对象
type Options struct{
timeout int,
trynums int
}
func NewClient(address string,opts Options){}
用对象的形式,还得检查参数的合法性。比如传递了不存在的参数等。
那么,我们看下用Functional Options Patter的方式,我写了一个简单的例子。
package main
import "fmt"
//如何向func传递默认值
type dialOption struct {
Username string
Password string
Service string
}
type DialOption interface {
apply(*dialOption)
}
type funcOption struct {
f func(*dialOption)
}
func(fdo *funcOption) apply(do *dialOption){
fdo.f(do)
}
func newFuncOption(f func(*dialOption))*funcOption{
return &funcOption{
f:f,
}
}
func withUserName(s string) DialOption{
return newFuncOption(func(o *dialOption){
o.Username = s
})
}
func withPasswordd(s string) DialOption{
return newFuncOption(func(o *dialOption){
o.Password = s
})
}
func withService(s string) DialOption{
return newFuncOption(func(o *dialOption){
o.Service = s
})
}
//默认参数
func defaultOptions() dialOption{
return dialOption{
Service:"test",
}
}
type clientConn struct {
timeout int
dopts dialOption
}
func NewClient(address string, opts ...DialOption){
cc :=&clientConn{
timeout:30,
dopts:defaultOptions(),
}
//循环调用opts
for _,opt := range opts {
opt.apply(&cc.dopts)
}
fmt.Printf("%+v",cc.dopts)
}
func main(){
NewClient("127.0.0.1",withPasswordd("654321"),withService("habox"))
NewClient("127.0.0.1",withService("habox"))
}
实例化时,通过func的方式来传递参数,也可以定义一些默认参数。如果以后要加,只需要更改很少的代码。
而且,这种方式也不会传递不相关的参数,因为参数都在通过func的方式来修改的。
唯一不好的地方可能是代码量相应的增加了。但是为了更优雅,这种做法还是值得的。
Golang中设置函数默认参数的优雅实现的更多相关文章
- C++函数重载遇到了函数默认参数情况
一.C++中的函数重载 什么是函数重载? 我的理解是: (1)用一个函数名定义不同的函数: (2)函数名和不同参数搭配时函数会有不同的含义: 举例说明: #include <stdio.h> ...
- (转)python中函数参数中如果带有默认参数list的特殊情况
在python中函数参数中如果带有默认参数list遇到问题 先看一段代码 1 2 3 4 5 6 7 8 9 def f(x,l=[]): for i in range(x): ...
- 如何在ES5与ES6环境下处理函数默认参数
函数默认值是一个很提高鲁棒性的东西(就是让程序更健壮)MDN关于函数默认参数的描述:函数默认参数允许在没有值或undefined被传入时使用默认形参. ES5 使用逻辑或||来实现 众所周知,在ES5 ...
- 【转】Python函数默认参数陷阱
[转]Python函数默认参数陷阱 阅读目录 可变对象与不可变对象 函数默认参数陷阱 默认参数原理 避免 修饰器方法 扩展 参考 请看如下一段程序: def extend_list(v, li=[]) ...
- Python面试题目之Python函数默认参数陷阱
请看如下一段程序: def extend_list(v, li=[]): li.append(v) return li list1 = extend_list(10) list2 = extend_l ...
- C++函数默认参数(转)
在代码中使用到了函数的默认参数,在函数的定义和实现中都填写的默认参数,结果出现了错误: 代码: #ifndef FIRSTPAGE_H #define FIRSTPAGE_H #include < ...
- Python进阶-函数默认参数
Python进阶-函数默认参数 写在前面 如非特别说明,下文均基于Python3 一.默认参数 python为了简化函数的调用,提供了默认参数机制: def pow(x, n = 2): r = 1 ...
- Python中list作为默认参数的陷阱
在Python中,作为默认参数的一定要是不可变对象,如果是可变对象,就会出现问题,稍不注意,就会调入陷阱,尤其是初学者,比如我(┬_┬). 我们来看一个例子. def add(L=[]): L.app ...
- linux中probe函数传递参数的寻找(下)
点击打开链接 linux中probe函数传递参数的寻找(下) 通过追寻driver的脚步,我们有了努力的方向:只有找到spi_bus_type的填充device即可,下面该从device去打通,当两个 ...
随机推荐
- docker研究-6 dockerfile 介绍使用
Dockerfile是用来创建镜像的,首字母必须大写.
- Centos 7 修改网卡名称、静态IP
修改内核选项 # vim /etc/sysconfig/grub GRUB_TIMEOUT= GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc ...
- 自动化部署-Jenkins备份回滚
1.备份 备份可以使用批处理命令解决,实际就是复制当前发布文件 ::备份文件夹名,使用当前时间 set foldername=%date:~0,4%%date:~5,2%%date:~8,2%%tim ...
- 简单的深度神经网络实现——使用PyTorch
使用的数据集是MNIST,预期可以达到98%左右的准确率. 该神经网络由一个输入层,一个全连接层结构的隐含层和一个输出层构建. 1.配置库和配置参数 import torch import torch ...
- HDU1213:How Many Tables(并查集入门)
-----------刷点水题练习java------------- 题意:给定N点,M边的无向图,问有多少个连通块. 思路:可以搜索; 可以并查集.这里用并查集练习java的数组使用,ans=N, ...
- day5_7.3 数据类型的各种函数操作
昨日补充: 1.在代码的编写中,总会有一些分支编写不出来,为了不影响整个系统的跑动,可以使用pass关键字进行跳过.如 count=0 while count<10: if count<5 ...
- InfoQ一波文章:菜鸟核心技术/Intel发布CPU新架构3D堆栈法/BDL/PaddlePaddle/百度第三代Spider/Tera
菜鸟智慧新物流核心技术全解析 孟靖 阅读数:63192018 年 12 月 14 日 16:00 2018 年天猫双 11 全球狂欢节已正式落下帷幕,最终成交额定格在 2135 亿元,物流订单 ...
- 浙大&川大提出脉冲版ResNet:继承ResNet优势,实现当前最佳
浙大&川大提出脉冲版ResNet:继承ResNet优势,实现当前最佳 选自arXiv,作者:Yangfan Hu等,机器之心编译. 脉冲神经网络(SNN)具有生物学上的合理性,并且其计算潜能和 ...
- 【oracle】存储过程:将select查询的结果存到变量中
- pyenv python 多版本管理工具
pyenv fork 自rbenv 以及ruby-build ,然后修改为转为python 使用 venv 以及virtualenv 解决了版本选择的问题,pyenv 同时为我们解决 了python ...