日常开发中,编程封装相关的可选库时,例如封装微信支付sdk、参数MySQL ORM、配置自定义的项配Server端等,都会给出很多相关的中使置配置,例如:
type Client struct {
host string
port string
timeout time.Duration
retryNum int
}
其中只有host和port是必选项,timeout和retryNum会给默认值,数式实现实例化这个结构体的编程时候这两个参数是可选的。
封装的可选库一般需要做到以下几点:
先通过一个代码片段来看一下使用函数式编程方式是怎么实现的:
package main
import (
"fmt"
"time"
)
type Client struct {
host string
port string
timeout time.Duration
retryNum int
}
type Option func(*Client)
func NewClient(host, port string, opt ...Option) *Client {
c := Client{
host: host,
port: port,
timeout: time.Second,
retryNum: 1,
}
for _, option := range opt {
option(&c)
}
return &c
}
func Timeout(timeout time.Duration) Option {
return func(c *Client) {
c.timeout = timeout
}
}
func RetryNum(num int) Option {
return func(c *Client) {
c.retryNum = num
}
}
使用方法是这样的,只传入必传参数。
func main() {
client := NewClient("localhost", "8080")
}
传入可选参数timeout:
func main() {
client := NewClient("localhost", "8080", Timeout(2*time.Second))
}
传入可选参数retryNum。
func main() {
client := NewClient("localhost", "8080", RetryNum(3))
}
传入timeout和retryNum。
func main() {
client = NewClient("localhost", "8080", Timeout(2*time.Second), RetryNum(3))
// 或者
// client = NewClient("localhost", "8080", RetryNum(3), Timeout(2*time.Second))
}
以上面的Timeout函数为例,这个函数返回的一个函数来设置传入的配置项,Timeout就是一个高阶函数。
上面的实现方式有个专业术语叫做 Functional Options,使用这种编程模式有很多好处:
(责任编辑:百科)
抢滩“宠物经济”前,你需要了解什么是真正的“宠物友好”...
爱司凯(300521.SZ)2020年度净亏损1214.64万元 不以公积金转增股本
汽车行业SaaS服务商『车巡IMS』获得3000万天使轮融资
安徽:截止10月底各级财政累计拨付民生工程资金1213.2亿元