精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Go編程模式:詳解函數式選項模式

開發 后端
Go 不是完全面向對象語言,有一些面向對象模式不太適合它。但經過這些年的發展,Go 有自己的一些模式。今天介紹一個常見的模式:函數式選項模式(Functional Options Pattern)。

[[437104]]

大家好,我是 polarisxu。

Go 不是完全面向對象語言,有一些面向對象模式不太適合它。但經過這些年的發展,Go 有自己的一些模式。今天介紹一個常見的模式:函數式選項模式(Functional Options Pattern)。

01 什么是函數式選項模式

Go 語言沒有構造函數,一般通過定義 New 函數來充當構造函數。然而,如果結構有較多字段,要初始化這些字段,有很多種方式,但有一種方式認為是最好的,這就是函數式選項模式(Functional Options Pattern)。

函數式選項模式是一種在 Go 中構造結構體的模式,它通過設計一組非常有表現力和靈活的 API 來幫助配置和初始化結構體。

在 Uber 的 Go 語言規范中提到了該模式:

Functional options 是一種模式,在該模式中,你可以聲明一個不透明的 Option 類型,該類型在某些內部結構中記錄信息。你接受這些可變數量的選項,并根據內部結構上的選項記錄的完整信息進行操作。

將此模式用于構造函數和其他公共 API 中的可選參數,你預計這些參數需要擴展,尤其是在這些函數上已經有三個或更多參數的情況下。

02 一個示例

為了更好的理解該模式,我們通過一個例子來講解。

定義一個 Server 結構體:

  1. package main 
  2.  
  3. type Server { 
  4.   host string 
  5.   port int 
  6.  
  7. func New(host string, port int) *Server { 
  8.   return &Server{host, port} 
  9.  
  10. func (s *Server) Start() error { 

如何使用呢?

  1. package main 
  2.  
  3. import ( 
  4.   "log" 
  5.   "server" 
  6.  
  7. func main() { 
  8.   svr := New("localhost", 1234) 
  9.   if err := svr.Start(); err != nil { 
  10.     log.Fatal(err) 
  11.   } 

但如果要擴展 Server 的配置選項,如何做?通常有三種做法:

為每個不同的配置選項聲明一個新的構造函數

定義一個新的 Config 結構體來保存配置信息

使用 Functional Option Pattern

做法 1:為每個不同的配置選項聲明一個新的構造函數

這種做法是為不同選項定義專有的構造函數。假如上面的 Server 增加了兩個字段:

  1. type Server { 
  2.  
  3. host string 
  4.  
  5. port int 
  6.  
  7. timeout time.Duration 
  8.  
  9. maxConn int 
  10.  

一般來說,host 和 port 是必須的字段,而 timeout 和 maxConn 是可選的,所以,可以保留原來的構造函數,而這兩個字段給默認值:

  1. func New(host string, port int) *Server { 
  2.  
  3. return &Server{host, port, time.Minute, 100} 
  4.  

然后針對 timeout 和 maxConn 額外提供兩個構造函數:

  1. func NewWithTimeout(host string, port int, timeout time.Duration) *Server { 
  2.  
  3. return &Server{host, port, timeout} 
  4.  
  5.  
  6. func NewWithTimeoutAndMaxConn(host string, port int, timeout time.Duration, maxConn int) *Server { 
  7.  
  8. return &Server{host, port, timeout, maxConn} 
  9.  

這種方式配置較少且不太會變化的情況,否則每次你需要為新配置創建新的構造函數。在 Go 語言標準庫中,有這種方式的應用。比如 net 包中的 Dial 和 DialTimeout:

  1. func Dial(network, address string) (Conn, error) 
  2.  
  3. func DialTimeout(network, address string, timeout time.Duration) (Conn, error) 

做法 2:使用專門的配置結構體

這種方式也是很常見的,特別是當配置選項很多時。通常可以創建一個 Config 結構體,其中包含 Server 的所有配置選項。這種做法,即使將來增加更多配置選項,也可以輕松的完成擴展,不會破壞 Server 的 API。

  1. type Server { 
  2.   cfg Config 
  3.  
  4. type Config struct { 
  5.   Host string 
  6.   Port int 
  7.   Timeout time.Duration 
  8.   MaxConn int 
  9.  
  10. func New(cfg Config) *Server { 
  11.   return &Server{cfg} 

在使用時,需要先構造 Config 實例,對這個實例,又回到了前面 Server 的問題上,因為增加或刪除選項,需要對 Config 有較大的修改。如果將 Config 中的字段改為私有,可能需要定義 Config 的構造函數。。。

做法 3:使用 Functional Option Pattern

一個更好的解決方案是使用 Functional Option Pattern。

在這個模式中,我們定義一個 Option 函數類型:

  1. type Option func(*Server) 

Option 類型是一個函數類型,它接收一個參數:*Server。然后,Server 的構造函數接收一個 Option 類型的不定參數:

  1. func New(options ...Option) *Server { 
  2.  
  3. svr := &Server{} 
  4.  
  5. for _, f := range options { 
  6.  
  7. f(svr) 
  8.  
  9.  
  10. return svr 
  11.  

那選項如何起作用?需要定義一系列相關返回 Option 的函數:

  1. func WithHost(host string) Option { 
  2.  
  3. return func(s *Server) { 
  4.  
  5. s.host = host 
  6.  
  7.  
  8.  
  9. func WithPort(port intOption { 
  10.  
  11. return func(s *Server) { 
  12.  
  13. s.port = port 
  14.  
  15.  
  16.  
  17. func WithTimeout(timeout time.Duration) Option { 
  18.  
  19. return func(s *Server) { 
  20.  
  21. s.timeout = timeout 
  22.  
  23.  
  24.  
  25. func WithMaxConn(maxConn intOption { 
  26.  
  27. return func(s *Server) { 
  28.  
  29. s.maxConn = maxConn 
  30.  
  31.  

針對這種模式,客戶端類似這么使用:

  1. package main 
  2.  
  3. import ( 
  4.  
  5. "log" 
  6.  
  7. "server" 
  8.  
  9.  
  10. func main() { 
  11.  
  12. svr := New( 
  13.  
  14. WithHost("localhost"), 
  15.  
  16. WithPort(8080), 
  17.  
  18. WithTimeout(time.Minute), 
  19.  
  20. WithMaxConn(120), 
  21.  
  22.  
  23. if err := svr.Start(); err != nil { 
  24.  
  25. log.Fatal(err) 
  26.  
  27.  

將來增加選項,只需要增加對應的 WithXXX 函數即可。

這種模式,在第三方庫中使用挺多,比如 github.com/gocolly/colly:

  1. type Collector { 
  2.  
  3. // 省略... 
  4.  
  5.  
  6. func NewCollector(options ...CollectorOption) *Collector 
  7.  
  8. // 定義了一系列 CollectorOpiton 
  9.  
  10. type CollectorOption{ 
  11.  
  12. // 省略... 
  13.  
  14.  
  15. func AllowURLRevisit() CollectorOption 
  16.  
  17. func AllowedDomains(domains ...string) CollectorOption 
  18.  
  19. ... 

不過 Uber 的 Go 語言編程規范中提到該模式時,建議定義一個 Option 接口,而不是 Option 函數類型。該 Option 接口有一個未導出的方法,然后通過一個未導出的 options 結構來記錄各選項。

Uber 的這個例子能看懂嗎?

  1. type options struct { 
  2.   cache  bool 
  3.   logger *zap.Logger 
  4.  
  5. type Option interface { 
  6.   apply(*options) 
  7.  
  8. type cacheOption bool 
  9.  
  10. func (c cacheOption) apply(opts *options) { 
  11.   opts.cache = bool(c) 
  12.  
  13. func WithCache(c bool) Option { 
  14.   return cacheOption(c) 
  15.  
  16. type loggerOption struct { 
  17.   Log *zap.Logger 
  18.  
  19. func (l loggerOption) apply(opts *options) { 
  20.   opts.logger = l.Log 
  21.  
  22. func WithLogger(log *zap.Logger) Option { 
  23.   return loggerOption{Log: log} 
  24.  
  25. // Open creates a connection
  26. func Open
  27.   addr string, 
  28.   opts ...Option
  29. ) (*Connection, error) { 
  30.   options := options{ 
  31.     cache:  defaultCache, 
  32.     logger: zap.NewNop(), 
  33.   } 
  34.  
  35.   for _, o := range opts { 
  36.     o.apply(&options) 
  37.   } 
  38.  
  39.   // ... 

03 總結

在實際項目中,當你要處理的選項比較多,或者處理不同來源的選項(來自文件、來自環境變量等)時,可以考慮試試函數式選項模式。

注意,在實際工作中,我們不應該教條的應用上面的模式,就像 Uber 中的例子,Open 函數并非只接受一個 Option 不定參數,因為 addr 參數是必須的。因此,函數式選項模式更多應該應用在那些配置較多,且有可選參數的情況。

參考文獻

https://golang.cafe/blog/golang-functional-options-pattern.html

https://github.com/uber-go/guide/blob/master/style.md#functional-options

責任編輯:武曉燕 來源: polarisxu
相關推薦

2022-11-06 23:17:23

Go語言項目

2010-07-15 17:58:31

Perl模式

2021-11-08 07:41:16

Go流水線編程

2022-04-24 15:29:17

微服務go

2023-04-10 09:20:13

設計模式訪客模式

2023-05-04 08:47:31

命令模式抽象接口

2021-07-12 10:24:36

Go裝飾器代碼

2023-05-15 08:51:46

解釋器模式定義

2014-04-25 10:13:00

Go語言并發模式

2022-02-21 08:15:15

Go項目語言

2012-04-05 11:52:43

ibmdw

2012-06-15 11:27:55

ibmdw

2021-06-29 08:54:23

設計模式代理模式遠程代理

2023-05-26 08:41:23

模式Go設計模式

2012-08-30 14:12:49

IBMdW

2025-03-24 00:25:00

Go語言并發編程

2021-07-07 10:31:19

對象池模式解釋器模式設計模式

2025-06-10 09:07:32

Go模式開發

2011-06-28 15:01:01

Qt PIMPL

2010-07-16 09:24:59

Perl模式
點贊
收藏

51CTO技術棧公眾號

7777精品伊人久久久大香线蕉完整版 | 农村寡妇一区二区三区| 国产成人无码精品久久久久| 亚洲香蕉视频| 欧美一区二区三区在线观看视频| 人妻夜夜添夜夜无码av| av在线天堂播放| 国产白丝精品91爽爽久久| 欧美性做爰毛片| 乱老熟女一区二区三区| 国产欧美三级电影| 欧美性三三影院| 欧美日韩不卡在线视频| 97在线观看免费观看高清| 成人午夜av影视| 国产欧美va欧美va香蕉在| 日韩成人av毛片| 99精品视频在线观看免费播放| 日韩av在线免费看| 91插插插影院| 88xx成人网| 欧美午夜女人视频在线| 激情五月六月婷婷| 在线a免费看| 久久亚洲捆绑美女| 国产精品久久久久久久天堂第1集| 成人一级免费视频| 中文亚洲免费| 欧美激情在线观看| 精品国产欧美日韩不卡在线观看| 狠狠做六月爱婷婷综合aⅴ| 亚洲电影第1页| 深夜福利网站在线观看| 福利视频一区| 色女孩综合影院| 日本韩国欧美在线观看| 丁香花在线高清完整版视频| 亚洲欧洲无码一区二区三区| 日韩黄色影视| 免费成人av电影| 91丝袜美腿高跟国产极品老师| 亚洲自拍欧美色图| 国产精品嫩草影院桃色| 美女尤物国产一区| 日韩免费在线观看视频| 青草视频在线观看免费| 在线一区免费观看| 91爱爱小视频k| 日本系列第一页| 亚洲婷婷在线| 久久人人爽人人爽人人片av高请| 丰满少妇高潮久久三区| 欧美在线黄色| 精品中文字幕视频| 九九热精品免费视频| 中文字幕一区二区三三| 欧美成人精品xxx| 精品99在线观看| 亚洲午夜电影| 久久久亚洲精选| 国产精品7777777| 亚洲永久视频| 国产97在线亚洲| www.久久久久久久| 免费在线一区观看| 成人激情黄色网| www.色呦呦| 成人av网站在线观看免费| 国产精品一码二码三码在线| 四虎在线视频免费观看| 久久亚洲欧美国产精品乐播| 视频一区视频二区视频| 日本高清视频在线播放| 亚洲女人的天堂| av在线观看地址| 涩涩视频在线| 欧美系列在线观看| 99精品视频国产| 伊人久久大香线蕉av超碰| 亚洲国产欧美一区二区丝袜黑人 | 激情婷婷综合| www国产精品视频| 九九视频免费观看| 国产精品美女| 国产日韩欧美在线播放| av网站在线免费看| 99re成人在线| 一区二区三区四区视频在线| 青草在线视频在线观看| 色综合中文字幕| 做a视频在线观看| www.成人网| 亚洲图中文字幕| 91视频综合网| 日韩精品国产欧美| 亚洲一区免费网站| 欧美日本网站| 亚洲精品成人精品456| 亚洲自偷自拍熟女另类| 999精品嫩草久久久久久99| 亚洲精品国产精品国产自| 亚洲一级黄色录像| 黄色日韩精品| 91精品久久久久久久久久久久久 | 国产欧美视频在线| 日韩精品免费在线视频观看| 我要看黄色一级片| 国产九九精品| 亚洲资源在线看| 福利在线观看| 婷婷久久综合九色综合绿巨人| 高清一区在线观看| 亚洲婷婷伊人| 久久久在线免费观看| 亚洲熟女乱色一区二区三区久久久| 成人在线综合网| 中文字幕成人一区| 欧美黑人一区| 亚洲国产成人爱av在线播放| 午夜爽爽爽男女免费观看| 久久天堂成人| 国产日产精品一区二区三区四区| 麻豆视频在线播放| 91久久精品国产91性色tv| 成人区人妻精品一区二| 亚洲最大黄网| 成人美女免费网站视频| 国产三级视频在线| 午夜日韩在线电影| 韩国一区二区三区四区| 四虎成人精品永久免费av九九| 欧美最顶级丰满的aⅴ艳星| 国产刺激高潮av| 亚洲激情自拍偷拍| 在线黄色免费观看| 精品精品99| 日韩免费黄色av| 久久久久久青草| 狠狠躁18三区二区一区| 国产精品手机在线观看| 好吊日精品视频| 91久久伊人青青碰碰婷婷| 成人在线影视| 日韩一区二区三免费高清| 免费看一级黄色| 六月丁香婷婷久久| 午夜精品一区二区三区四区| 亚洲mmav| 中文字幕在线视频日韩| 国产免费一区二区三区四区五区 | 欧美一区二区三区不卡| 九九热视频在线免费观看| 麻豆视频一区二区| 亚洲欧美日韩精品在线| 免费一区二区三区四区| 少妇高潮久久77777| 精品国产www| 国产精品精品国产色婷婷| www.超碰97.com| 五月天久久777| 成人做爽爽免费视频| 黄色网址在线免费观看| 欧美一区二区成人6969| 国产a免费视频| 成人动漫一区二区| 欧美爱爱视频免费看| 伊人久久大香线蕉av不卡| 日韩av免费网站| 99免在线观看免费视频高清| 欧美久久一区二区| 久久久99精品| 91小视频免费看| 动漫av免费观看| 香蕉av一区二区| 国产v亚洲v天堂无码| 性欧美18~19sex高清播放| 国产一区二区三区高清在线观看| 97在线公开视频| 亚洲一二三四久久| 精品无码人妻一区二区免费蜜桃| 久久精品久久综合| 2022中文字幕| 欧美男gay| 91久久国产精品91久久性色| а√天堂中文资源在线bt| 亚洲性夜色噜噜噜7777| 国产美女免费视频| 性做久久久久久免费观看欧美| 性高潮久久久久久久| 国产精品伊人色| 国产精品333| 天天插综合网| 黄色99视频| 自拍偷拍亚洲| 国产91精品久久久| 国产剧情在线| 日韩精品免费电影| 国产毛片毛片毛片毛片| 欧美日韩精品在线观看| 三级黄色在线观看| 96av麻豆蜜桃一区二区| 一级黄色片国产| 国产精品呻吟| 加勒比海盗1在线观看免费国语版| 香蕉久久夜色精品国产更新时间| 国产一区私人高清影院| 女人让男人操自己视频在线观看| 精品国产自在精品国产浪潮| 日本五码在线| 欧美xxxx在线观看| 影音先锋国产资源| 精品人伦一区二区三区蜜桃免费| 日韩国产第一页| 日本一区二区三区高清不卡| 国产肉体xxxx裸体784大胆| 国产一区二区女| 五月婷婷激情久久| 99成人免费视频| 激情六月天婷婷| 天堂美国久久| 午夜精品一区二区在线观看| 日韩成人av在线资源| 鬼打鬼之黄金道士1992林正英| 日韩一级特黄| 国产精品电影观看| 欧美亚洲日本精品| 久久久久久国产免费| 麻豆av在线导航| 日日摸夜夜添一区| 国产玉足榨精视频在线观看| 日韩精品免费综合视频在线播放 | 动漫av网站免费观看| 国产精品观看| 国产成人生活片| 国产精品精品| 一本一道久久久a久久久精品91| 亚洲黄页网站| 久久99精品久久久久子伦| 久久久亚洲欧洲日产| 97神马电影| 午夜久久av| 国产精品久久久久久免费观看| 亚洲精品aⅴ| 亚洲xxxx3d| 日韩精品中文字幕一区二区 | 91精品国产777在线观看| 不卡av免费观看| 久久免费在线观看| a在线视频v视频| 69影院欧美专区视频| 欧美久久天堂| 日本不卡高字幕在线2019| 亚洲精品福利电影| 国产999精品| 成人四虎影院| 亚洲伊人久久大香线蕉av| 榴莲视频成人app| 99久热re在线精品996热视频| 视频一区国产| 久久精品国产美女| 国产成人一区| 亚洲永久激情精品| 91精品国产91久久久久久密臀| 日本丰满大乳奶| 亚洲视频一区| av网址在线观看免费| 欧美96一区二区免费视频| www.com久久久| 国产1区2区3区精品美女| 日本国产在线视频| 久久综合九色综合97婷婷女人| 摸摸摸bbb毛毛毛片| 亚洲天堂成人网| 日本最新中文字幕| 色视频欧美一区二区三区| 中文字幕+乱码+中文乱码91| 欧美一区二区三区系列电影| 日本美女一级视频| 亚洲热线99精品视频| 天堂中文а√在线| 久久久久久成人精品| gay欧美网站| 91在线免费网站| 欧美激情极品| 亚洲精品中文字幕乱码三区不卡| 伊人久久大香线蕉精品组织观看| 精品视频免费在线播放| 日本女人一区二区三区| 亚洲妇女无套内射精| 久久综合av免费| 午夜免费激情视频| 日韩欧美999| 国产乱淫片视频| 亚洲欧美日本精品| 69成人在线| 国产精品96久久久久久| 亚洲精品国产九九九| 日韩欧美三级电影| 亚洲国产精品第一区二区| 人人爽人人av| 成人精品国产一区二区4080| 青青青视频在线播放| 亚洲午夜久久久久久久久电影网| 高潮无码精品色欲av午夜福利| 精品成人一区二区| 日韩专区在线| 欧美亚洲成人免费| 亚洲天堂中文字幕在线观看| 日韩伦理一区二区三区av在线| 怡红院精品视频在线观看极品| 九九精品久久久| 2021国产精品久久精品| 欧美人与禽zozzo禽性配| 欧美专区在线观看一区| 天堂成人在线观看| 久久成人精品视频| 国产三级一区| 欧洲精品久久| 亚洲少妇一区| www国产视频| 亚洲欧美成人一区二区三区| 精品人妻一区二区三区潮喷在线| 欧美草草影院在线视频| 欧美r级在线| 国产精品国产三级国产专播精品人 | 一本色道久久综合精品竹菊| 黄色一级a毛片| 欧美另类暴力丝袜| 欧美一区二区三区婷婷| 日韩久久不卡| 久久人人精品| 尤物视频最新网址| 欧美午夜视频在线观看| 天天干,天天操,天天射| 久久久久久久久亚洲| 亚洲大奶少妇| 91免费国产精品| 国产成人精品免费| 久久黄色免费视频| 91精品国产综合久久婷婷香蕉| 黄黄的网站在线观看| 91亚洲国产成人精品性色| 五月婷婷六月综合| 天堂av8在线| 亚洲人精品午夜| av免费在线观看不卡| 欧美另类在线播放| 96sao在线精品免费视频| 免费人成在线观看视频播放| 成人福利电影精品一区二区在线观看| 国产无遮挡免费视频| 亚洲第一页中文字幕| 手机在线观看av网站| 久久综合精品一区| 久久成人国产| 男女男精品视频网站| 91精品国产一区二区三区蜜臀| 午夜av在线免费观看 | 亚洲电影一级片| 国产精品少妇在线视频| 中文字幕+乱码+中文字幕一区| 中文字幕欧美在线观看| www国产精品视频| 一区二区三区国产好| 免费毛片网站在线观看| wwww国产精品欧美| 久久精品国产亚洲av麻豆蜜芽| 日韩中文字幕在线视频| 日韩中文字幕无砖| 成年人午夜视频在线观看| 久久久久99精品一区| 一区二区三区黄| 久久欧美在线电影| 欧美日韩国产一区二区三区不卡 | 久久久久久久亚洲| 主播福利视频一区| 日韩精品一区二区三区中文 | 一区精品在线| 国产69精品久久777的优势| 97久久久久久久| 视频直播国产精品| 8848成人影院| 最近免费中文字幕中文高清百度| 中文字幕一区二区三区精华液| 好吊色一区二区三区| 国产成人精品日本亚洲专区61 | 1024av视频| 国产精品久久久久精k8| 免费观看国产精品| 国产精品久久久久久久久久小说| 亚洲精品tv久久久久久久久久| 日韩免费高清一区二区| 欧美日韩国产123区| 不卡的av影片| 在线观看一区欧美| 久久综合色天天久久综合图片| 国产精品热久久| 欧美在线视频观看免费网站| 午夜精品av| 免费成人深夜蜜桃视频|