在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中设置函数默认参数的优雅实现的更多相关文章

  1. C++函数重载遇到了函数默认参数情况

    一.C++中的函数重载 什么是函数重载? 我的理解是: (1)用一个函数名定义不同的函数: (2)函数名和不同参数搭配时函数会有不同的含义: 举例说明: #include <stdio.h> ...

  2. (转)python中函数参数中如果带有默认参数list的特殊情况

    在python中函数参数中如果带有默认参数list遇到问题 先看一段代码 1 2 3 4 5 6 7 8 9 def f(x,l=[]):     for i in range(x):         ...

  3. 如何在ES5与ES6环境下处理函数默认参数

    函数默认值是一个很提高鲁棒性的东西(就是让程序更健壮)MDN关于函数默认参数的描述:函数默认参数允许在没有值或undefined被传入时使用默认形参. ES5 使用逻辑或||来实现 众所周知,在ES5 ...

  4. 【转】Python函数默认参数陷阱

    [转]Python函数默认参数陷阱 阅读目录 可变对象与不可变对象 函数默认参数陷阱 默认参数原理 避免 修饰器方法 扩展 参考 请看如下一段程序: def extend_list(v, li=[]) ...

  5. Python面试题目之Python函数默认参数陷阱

    请看如下一段程序: def extend_list(v, li=[]): li.append(v) return li list1 = extend_list(10) list2 = extend_l ...

  6. C++函数默认参数(转)

    在代码中使用到了函数的默认参数,在函数的定义和实现中都填写的默认参数,结果出现了错误: 代码: #ifndef FIRSTPAGE_H #define FIRSTPAGE_H #include < ...

  7. Python进阶-函数默认参数

    Python进阶-函数默认参数 写在前面 如非特别说明,下文均基于Python3 一.默认参数 python为了简化函数的调用,提供了默认参数机制: def pow(x, n = 2): r = 1 ...

  8. Python中list作为默认参数的陷阱

    在Python中,作为默认参数的一定要是不可变对象,如果是可变对象,就会出现问题,稍不注意,就会调入陷阱,尤其是初学者,比如我(┬_┬). 我们来看一个例子. def add(L=[]): L.app ...

  9. linux中probe函数传递参数的寻找(下)

    点击打开链接 linux中probe函数传递参数的寻找(下) 通过追寻driver的脚步,我们有了努力的方向:只有找到spi_bus_type的填充device即可,下面该从device去打通,当两个 ...

随机推荐

  1. odoo10学习笔记十二:web controller

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/11189332.html 一:路由 odoo.http.route(route=None, **kw) 装饰器 ...

  2. ansible 模块 roles

    setup 作用,用来查看用看内部的详细信息 ansible_all_ipv4_addresses # ipv4的所有地址 ansible_all_ipv6_addresses # ipv6的所有地址 ...

  3. Mysql使用语法总结

    查看数据库 show databases; 使用数据库 use honeypot; 查看数据表 show tables; 查看数据表结构 desc TABLEname; 修改数据表的某个字段的类型 a ...

  4. 201871010131-张兴盼《面向对象程序设计(java)》第十一周学习总结

    项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/ ...

  5. springboot常见问题

    什么是 Spring Boot? 为什么要用 Spring Boot? Spring Boot 的核心配置文件有哪几个?它们的区别是什么? Spring Boot 的配置文件有哪几种格式?它们有什么区 ...

  6. 02-numpy-笔记-amin

    >>> a = np.arange(4).reshape((2,2)) >>> a array([[0, 1], [2, 3]]) >>> np. ...

  7. This server is in the failed servers list: localhost/127.0.0.1:16000 启动hbase api调用错误

    api 调用发现错误 Mon Nov 18 23:04:31 CST 2019, RpcRetryingCaller{globalStartTime=1574089469858, pause=100, ...

  8. 5 Ways AI is Transforming the Finance Industry

    https://marutitech.com/ways-ai-transforming-finance/ As global technology has evolved over the years ...

  9. ubuntu安装dia

    linux下一款不错的流程图工具:dia.安装此工具:1.打开终端(快捷键:ctrl+alt+t).2.输入命令: $sudo apt-get install dia 3.提示“解压缩后会消耗掉 20 ...

  10. pagehelper超过页数仍然可以查出数据

    spring boot中pageHelper的使用 pom文件中添加 <!--pagehelper --> <dependency> <groupId>com.gi ...