在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. easy-copy服务器文件拷贝简易小工具

    github:easy-copy import os import sys import time import paramiko as pm ''' host格式: { "ip" ...

  2. UE4 C++中出现的让人手足无措的问题(持续更新)

    最近开始涉入UE4更深层的一面——UE4 C++,由于其中的体系和在课本或者是网课上那么说的C++体系有一些误差(准确说就是遵循的C++标准不同),导致学习与运用起来有些吃力,所以作此总结,为自己的开 ...

  3. Rocketmq原理&最佳实践

    MQ背景&选型 消息队列作为高并发系统的核心组件之一,能够帮助业务系统解构提升开发效率和系统稳定性.主要具有以下优势: 削峰填谷(主要解决瞬时写压力大于应用服务能力导致消息丢失.系统奔溃等问题 ...

  4. 201871010133-赵永军《面向对象程序设计(java)》第七周学习总结

    201871010133-赵永军<面向对象程序设计(java)>第七周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这 ...

  5. 莫烦RL-01小例子

    # Python 3.6.5 :: Anaconda, Inc. import numpy as np import pandas as pd import time np.random.seed(2 ...

  6. Vue小练习(for循环,push方法,冒泡,if判断(以及与for循环的连用),按钮高亮,根据input框筛选数据)

    vue练习 ''' 1. 先有一下成绩单数据 scores = [ { name: 'Bob', math: 97, chinese: 89, english: 67 }, { name: 'Tom' ...

  7. JDOJ 1770 埃及分数

    JDOJ 1770: 埃及分数 https://neooj.com/oldoj/problem.php?id=1770 Description 分子均为1的分数叫做埃及分数,因为古代埃及人在进行分数运 ...

  8. .Net反射-Type类型扩展

    /// <summary> /// Type 拓展 /// </summary> public static class TypeExtensions { /// <su ...

  9. vscode用服务打开html

    ①安装插件 此时右击会有: ②anywhere

  10. LOJ6686 Stupid GCD(数论,欧拉函数,杜教筛)

    做题重心转移到 LOJ 了. 至于为什么,如果你知道“……”的密码,就去看吧. LOJ 上用户自创题大多数都不可做,今天看到个可做题(而且还是个水题),就来做了一发. 明显枚举立方根.(以下令 $m= ...