范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Go语言实践模式函数选项模式(FunctionalOptionsPattern)

  什么是函数选项模式
  大家好,我是小白,有点黑的那个白。
  最近遇到一个问题,因为业务需求,需要对接第三方平台.
  而三方平台提供的一些HTTP(S)接口都有统一的密钥生成规则要求.
  为此我们封装了一个独立的包 xxx-go-sdk 以便维护和对接使用.
  其中核心的部分是自定义HTTP Client,如下: type Client struct {}  func (c *Client) do() {       // 实现统一的加密和签名逻辑       // 统一调用net/http }  // 订单列表接口 func (c *Client) OrderList(){       c.do() }   // 订单发货接口 func (c *Client) OrderDelivery(){       c.do() }  // ... 其他接口
  一些平台会要求appKey/appSecret等信息,所以Client结构体就变成了这样,这时参数还比较少, 而且是必填的参数,我们可以提供构造函数来明确指定。 type Client struct {       AppKey     string       AppSecret string }  func NewClient(appKey string, appSecret string) *Client {      c := new(Client)      c.AppKey = appKey      c.AppSecret = appSecret      return c }
  看起来很满足,但是当我们需要增加一个 Timeout 参数来控制超时呢?
  或许你会说这还不简单,像下面一样再加一个参数呗 type Client struct {       AppKey     string       AppSecret string       Timeout    time.Duration }  func NewClient(appKey string, appSecret string, timeout time.Duration) *Client {      c := new(Client)      c.AppKey = appKey      c.AppSecret = appSecret      c.Timeout = timeout      return c }
  那再加些其他的参数呢?那构造函数的参数是不是又长又串,而且每个参数不一定是必须的,有些参数我们又会考虑默认值的问题。
  为此,勤劳但尚未致富的 gophers 们使用了总结一种实践模式
  首先提取所有需要的参数到一个独立的结构体 Options,当然你也可以用 Configs 啥的. type Options struct {       AppKey       string       AppSecret string }
  然后为每个参数提供设置函数 func WithAppKey(appKey string) func(*Options) {       return func(o *Options) {             o.AppKey = appKey       } }  func WithAppSecret(appSecret string) func(*Options) {       return func(o *Options) {             o.AppSecret = appSecret       } }
  这样我们就为每个参数设置了独立的设置函数。返回值  func(*Options)  看着有点不友好,我们提取下定义为单个 Option  调整一下代码type Option func(*Options)  func WithAppKey(appKey string) Option {       return func(o *Options) {             o.AppKey = appKey       } }  func WithAppSecret(appSecret string) Option {       return func(o *Options) {             o.AppSecret = appSecret       } }
  当我们需要添加更多的参数时,只需要在 Options 添加新的参数并添加新参数的设置函数即可。
  比如现在要添加新的参数 Timeout type Options struct {       AppKey       string       AppSecret   string       Timeout.     time.Duration // 新增参数 }  // Timeout 的设置函数 func WithTimeout(timeout time.Duration) Option {       return func(o *Options) {             o.Timeout = timeout       } }
  这样后续不管新增多少参数,只需要新增配置项并添加独立的设置函数即可轻松扩展,并且不会影响原有函数的参数顺序和个数位置等。
  至此,每个选项是区分开来了,那么怎么作用到我们的 Client 结构体上呢?
  首先,配置选项都被提取到了 Options 结构体重,所以我们需要调整一下 Client 结构体的参数 type Client struct {       options *Options }
  其次,每一个选项函数返回 Option,那么任意多个就是 ...Option,我们调整一下构造函数 NewClient 的参数形式,改为可变参数,不再局限于固定顺序的几个参数。 func NewClient(options ...Option) *Client {     c := new(Client)     c.Options = ?     return c }
  然后循环遍历每个选项函数,来生成Client结构体的完整配置选项。 func NewClient(options ...Option) *Client {      opts := new(Options)      for _, o := range options {           o(opts)     }     c := new(Client)     c.Options = opts     return c }
  那么怎么调用呢?对于调用方而已,直接在调用构造函数NewClient()的参数内添加自己需要的设置函数(WithXXX)即可 client := NewClient(      WithAppKey("your-app-key"),      WithAppSecret("your-app-secret"), )
  当需要设置超时参数,直接添加 WithTimeout即可,比如设置3秒的超时 client := NewClient(      WithAppKey("your-app-key"),      WithAppSecret("your-app-secret"),      WithTimeout(3*time.Second), )
  配置选项的位置可以任意设置,不需要受常规的固定参数顺序约束。
  可以看到,这种实践模式主要作用于配置选项,利用函数支持的特性来实现的,为此得名 Functional Options Pattern,优美的中国话叫做「函数选项模式」。 总结
  最后, 我们总结回顾一下在Go语言中函数选项模式的优缺点 优点支持多参数; 支持参数任意位置顺序; 支持默认值设置; 向后兼容,扩展性极佳; 用户使用行为一致, 体感良好. 缺点
  这是特性,不是缺点 - -!  增加了Options结构和Option定义; 针对每个参数都有对应的设置函数,每个选项函数的实现代码量好像多了一些;

网络空间主权资源及网络安全的目的网络空间是人类创造的新的生产与生活空间,是继陆海空天之后的第五空间。在这个新的人类空间里每个国家占有多大范围?有什么特殊资源?这是涉及网络主权和网络资源的所有权归属的大是大非问题。歌尔股份公司已经积累了AR核心器件模组以及AR整机项目的相关项目经验36氪获悉,歌尔股份在互动平台表示,公司看好VRAR行业的未来发展,并在相关领域内进行了相应的人才技术和产品布局。公司可以为客户提供AR光学器件及模组AR光机等核心零组件以及AR整一个没有正式工作的女性,却有三百多个微信好友,这种情况正常吗?自从堂哥出去打工以后,堂嫂已经连续多年没有工作了,在家也不照顾孩子,还经常和不同的男人来往,婶子让堂哥离婚,直到去年,我发现了堂嫂的一个秘密后,我对婶子说,如果堂哥真的和堂嫂离婚了奶奶看电视声音开很大声都听不清楚,戴上助听器能听见电视的声音吗?你好,估计是你奶奶的听力出现了问题,一般戴上助听器经过康复后是可以听清楚电视的声音,建议带上奶奶去当地的听力机构咨询检查听力。助听器可以帮助老人听到声音,戴上助听器的效果也同自己的腾讯优酷和爱奇艺相比,哪个视频软件好?极客谈科技局,全新视角全新思路,伴你遨游神奇的科技世界。在我们平时的生活中,腾讯优酷爱奇艺,是我们平时追剧的三大神器,看电视剧网剧电影综艺等节目,基本都要用到这几个视频播放软件,记TWS市场进入洗牌期,电源管理技术日趋成熟电子发烧友网报道(文黄山明)就在不久前,苹果刚举办完新品发布会,值得注意的是,此次苹果发布了新款的AirPods3,也是自AirPods系列发布以来的第五个年头,或者说是TWS耳机曹晓烨刘东现货互联网交易犯罪的刑事责任研究曹晓烨上海市杨浦区人民检察院副检察长刘东上海市杨浦区人民检察院第六检察部检察官助理。内容摘要现货互联网交易犯罪涉案人员众多涉案金额巨大,严重侵害投资者的财产权益,强烈冲击着我国现货杭州是不是只用支付宝结账?可以很明确的说杭州不拒绝微信付款,作为移动支付之城,微信和支付宝都是可以用的支付方式。商家收款如果只支持支付宝,这等于是抛弃部分用微信支付的用户,商家可不会这么傻。不少用户在杭州完VR技术现在发展到什么地步了?前段时间热映的电影头号玩家,一度引起了人们的热议。除了精彩的故事情节之外,电影中游戏玩家们超级炫酷的VR虚拟世界的游戏体验,引起了大家的热议。人们不禁想问近几年来就一直频繁地听到V你看好腾讯微视的未来吗?经过一年多的发展,抖音自2018年春节之后达到了高光时间,至今热度一直不减。此前,关于抖音狙击快手灭掉微博杀死朋友圈的报道不断。加上微信QQ用户同比增幅的下滑,以及抖音用户的暴增和如何看待iPhoneX取消运营商文字显示这件事?据说,新出炉的iPhoneX在刚刚出世就面对很多争议,不仅是头顶上有个刘海,更严重的是,苹果新版的手机取消了电信运营商名称的显示。多家外媒报道,在以往的iPhone或者其他安卓手机
要想K歌效果好,KTV音箱用什么喇叭好?相信不少的人都会有这样的疑问,KTV音箱用什么喇叭好?不同档次的包房以及包房的大小所适合的音箱喇叭是不一样的,现在一般的KTV包房首先要满足的是卡拉OK的歌唱功能,其次是听歌跳舞。下半年值得选的两款手机,一款红米一款华为,价格大跌口碑大涨回看上半年发布的安卓手机,有一些正逐渐降价中,但它们的口碑并不是很高,有一些虽然值得入手,但价格劝退了不少用户,因此在众多机型中挑来挑去,笔者发现有两款手机值得一看,分别是红米的R新一代金属全面屏让电视更好看了它是金属全面屏,也是客厅风景,打开电视一瞬间,震撼色彩铺满整个画面,奔放自由冲破你视线中的所有条条框框,它就是小米EA502022款全面屏电视。小米EA502022款全面屏电视小米你有用了五年以上的手机?什么原因导致你用了这么久?红米NOt4用了五年,现在还是备用机,手机用多久因人而异,不玩游戏正常使用,小米手机性价比与质量还是最好的!Nokia6120c2007123120151025NokiaLumia美国为什么要向三星和台积电索要数据,背后有什么深层原因?美国的霸权主义是无所不在的!美国的科技霸权是支撑其全球军事霸权的核心,军事霸权又是支撑经济霸权和美元霸权的保证,经济霸权和美元霸权又为政治霸权提供金钱保障,政治霸权最终负责分配维护为什么这么多人喜欢今日头条?感谢邀请,吾认为今日头条是一座知识宝库。古今中外历史文化科技军事知识应有尽有,既有文字,又有视频,形式多样,异彩纷呈,如一座知识宝库。今日头条是一所没有围墙的学校。在这里想学的东西在网上买了一个助听器,戴上感觉很吵,有没有没有杂音的助听器?去正规的商店购买网上买的助听器,没有根据听力验配,调试,而且一般网上的都是模拟机,没有降噪的性能,把所有的声音都一比一的放大,大中小的声音同等放大,而且没有降噪,戴上会伤害听力,会邻居一直蹭我家网络,修改密码后,竟然剪我网线,应该怎么做?网络维修人员来修两次以后让他报警。破坏网络电缆要付刑事责任。不要私自交涉。那不光没有用还会增加纠纷。让他连,给他限速,他就没理由了不能拿怀疑当证据,摊上这样的邻居也没办法了,我们家本人女,30岁,想收入高一点还债,是不是跑滴滴比较好?跑滴滴年入过万不是梦做直播,一个月有一两万结婚了吗?没结婚找个老公就可以了,你老公会帮你还现在欠外债,还最好最快的方式应该就是直播,直播给了很多平凡人翻身的机会。挣钱快但也不是那么国产手机何时才能从苹果手里夺回高端市场?只要华为解决了芯片问题就可以了!苹果的成功短期内难以复制,其洋品牌的身份给其加分不少。国内最接近的品牌是华为,可惜华为被美国无理由的制裁。小米OV之流的一年发布几十上百款款手机,大如果QQ和微信不兼容苹果手机,它的销量在国内能跌九成吗?我个人认为,腾讯,作为一家企业,不会轻易放弃任何一个手机系统,因为苹果的用户数在全球也是非常可观的,如果拒绝与苹果合作,敌伤1000,自损800,这种事腾讯不会做!那么腾讯放弃io