精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

精品成人在线| 国产成人福利av| 综合中文字幕亚洲| 91手机在线视频| 人妻丰满熟妇av无码区| 欧美限制电影| 精品少妇一区二区三区免费观看| 3d动漫一区二区三区| 97视频在线观看网站| 国产成人精品一区二| 欧美在线亚洲一区| 九九精品视频免费| 亚洲人成亚洲精品| 欧美成人午夜电影| 天天干在线影院| 好吊日av在线| 国产精品你懂的| 久99久在线| 97精品久久人人爽人人爽| 亚洲激情视频| 久久视频免费观看| 91精彩刺激对白露脸偷拍| 国产在线视频欧美一区| 欧美性猛交xxxx乱大交| 91传媒免费视频| 在线视频二区| 久久综合成人精品亚洲另类欧美| 亚洲一区二区三区xxx视频| chinese国产精品| 国内久久视频| 操日韩av在线电影| 美国一级黄色录像| 天天躁日日躁成人字幕aⅴ| 欧美一级精品在线| 精品999在线| 欧美aa一级| 亚洲激情一二三区| 在线观看一区二区三区三州| 色资源在线观看| 丁香天五香天堂综合| 国产色婷婷国产综合在线理论片a| 国产精品suv一区二区三区| 欧美粗暴jizz性欧美20| 日韩中文字幕免费视频| 久久视频精品在线观看| 亚洲日本三级| 日韩电影中文 亚洲精品乱码| 乳色吐息在线观看| 成人在线分类| 欧美一区日本一区韩国一区| 成人免费视频久久| 中文字幕在线看片| 欧美日韩亚洲一区二区三区| 日本人妻伦在线中文字幕| 成人在线播放免费观看| 国产精品护士白丝一区av| 欧洲高清一区二区| 国产69久久| 国产欧美日韩在线| 亚洲电影一二三区| 成人av毛片| 国产精品午夜免费| 夜夜爽www精品| 久草免费在线| 亚洲精品免费在线观看| 一本色道久久综合亚洲精品婷婷| av在线第一页| 国产精品久久久爽爽爽麻豆色哟哟| 欧美污视频久久久| 国产在线观看网站| 国产精品麻豆网站| 二级片在线观看| 污污的视频在线观看| 亚洲一二三四在线| 欧美 日本 亚洲| 久久夜夜操妹子| 欧美日韩国产乱码电影| 男女污污视频网站| 97精品久久| 国产视频精品自拍| a∨色狠狠一区二区三区| 国产69精品久久99不卡| 国产精品制服诱惑| 人成免费电影一二三区在线观看| 久久五月婷婷丁香社区| 先锋影音一区二区三区| 麻豆网站在线看| 曰韩精品一区二区| 日韩免费一级视频| 欧美jizz18| 欧美不卡一区二区三区| 国产特黄级aaaaa片免| 欧美理论在线播放| 欧美成人剧情片在线观看| 国产一级二级三级| 美女尤物久久精品| 亚洲综合色激情五月| 天天色综合av| 国产精品美女久久久久aⅴ国产馆| 黑人巨大国产9丨视频| 999av小视频在线| 欧美性受极品xxxx喷水| 色黄视频免费看| 午夜先锋成人动漫在线| 精品国产自在精品国产浪潮| 国产在线一区视频| 免费成人美女在线观看.| 91精品黄色| av在线三区| 欧美日韩另类视频| 超碰在线资源站| 一区二区导航| 欧美富婆性猛交| 中文字幕精品无| 成人高清视频在线观看| 亚洲一区在线免费| 久久电影tv| 精品国产精品网麻豆系列 | 麻豆国产尤物av尤物在线观看| 亚洲日本免费| 亚洲iv一区二区三区| 国际av在线| 偷拍与自拍一区| 黄色片子免费看| 欧美一区电影| 欧美做爰性生交视频| 亚洲精品成av人片天堂无码| 国产精品乱码一区二三区小蝌蚪| 国产深夜男女无套内射| 久久视频免费| 北条麻妃在线一区二区| 亚洲第一区av| 久久久久久亚洲综合影院红桃 | 国产精品久久久久久久久久直播| 91这里只有精品| 色悠悠久久综合| chinese麻豆新拍video| 国产综合亚洲精品一区二| 91久久中文字幕| 日本蜜桃在线观看| 欧美亚洲国产一区二区三区| 久久人人妻人人人人妻性色av| 国产一区欧美| 97超碰人人看人人| 欧美videossex另类| 欧美一区二区三区视频在线| 欧美一区二区三区观看| 免费成人性网站| 午夜精品视频在线观看一区二区 | 国产精品丝袜白浆摸在线| 日本中文字幕一区二区有码在线| 亚洲成人综合视频| 国产人成视频在线观看| 亚洲黄色影片| 精品综合久久久| 午夜伦理福利在线| 亚洲视频免费一区| 少妇久久久久久久| 亚洲国产激情av| av中文字幕网址| 亚洲人成免费网站| 成人一区二区三区四区| 里番在线播放| 亚洲国产欧美久久| 性无码专区无码| 91女神在线视频| 久久精品免费网站| 97久久视频| 51国偷自产一区二区三区| 手机av免费在线| 亚洲国产一区二区三区在线观看| 天堂网一区二区三区| 91欧美一区二区| 国内外成人免费在线视频| 国产精品7m凸凹视频分类| 91免费看国产| free性护士videos欧美| 亚洲欧美中文另类| 亚洲手机在线观看| 亚洲综合另类小说| 性欧美丰满熟妇xxxx性仙踪林| 日韩和欧美的一区| 国产日产欧美一区二区| 美女av一区| 国产精品久久久久久亚洲影视| 日本美女高清在线观看免费| 日韩写真欧美这视频| 91看片在线播放| 国产女人水真多18毛片18精品视频| 五月婷婷六月丁香激情| 欧美午夜久久| 欧美一区二区三区精美影视| 日韩免费在线电影| 91国产精品电影| 在线视频二区| 日韩电影中文 亚洲精品乱码| 懂色av中文字幕| 亚洲精品ww久久久久久p站 | 中文字幕欧美一区| 年下总裁被打光屁股sp| 狂野欧美一区| 精品视频在线观看一区二区| 美女网站一区| av一区二区三区免费| 色综合一本到久久亚洲91| 久久影院在线观看| 国产精品久久久久久久龚玥菲 | 欧美美乳在线| 在线不卡一区二区| 性色av免费观看| 一个色在线综合| 国产调教在线观看| 97久久人人超碰| 樱花草www在线| 丝瓜av网站精品一区二区| 日韩a级黄色片| 99久久精品费精品国产| 欧美lavv| 国产伦精品一区二区三区免费优势| 国产精品永久免费| 日韩中文影院| 91av成人在线| 男女在线观看视频| 久久久国产视频91| 高清av电影在线观看| 日韩福利在线播放| 国 产 黄 色 大 片| 91精品国产综合久久精品性色| 无码人妻av一区二区三区波多野 | 久久久国产一区二区三区| 都市激情一区| 亚洲欧美日韩天堂一区二区| 丰满人妻熟女aⅴ一区| 欧美一区三区二区| 国产精品国产一区二区三区四区 | 国产精品久久久久久久蜜臀| 亚洲男人在线天堂| 不卡一区在线观看| 久久久久久久久久影视| 国产精品一区二区黑丝| www.51色.com| 国产伦理精品不卡| 亚洲热在线视频| 国产一区二区影院| 交换做爰国语对白| 国产一区二区免费看| 亚洲一二三av| 国产在线精品一区二区夜色| 亚洲综合婷婷久久| 国产真实乱对白精彩久久| 91丨九色丨蝌蚪| 国产又黄又大久久| 日日夜夜精品视频免费观看| 国产一区欧美日韩| 国产调教打屁股xxxx网站| 国产一区二区精品久久| 亚洲一区二区中文字幕在线观看| 九九视频精品免费| 97超碰人人看| 成人h动漫精品一区二区| 黄色激情在线观看| 99精品国产热久久91蜜凸| 国产精品嫩草av| 久久综合精品国产一区二区三区| 中文字幕一区二区三区人妻不卡| 久久久久久影视| 91无套直看片红桃在线观看| 中文字幕一区二区三区视频| 欧美做爰爽爽爽爽爽爽| 一区二区三区中文在线观看| 日本熟妇成熟毛茸茸| 舔着乳尖日韩一区| 波多野结衣一区二区三区在线| 欧美日韩一区视频| 国产白浆在线观看| 精品香蕉在线观看视频一| 精品99又大又爽又硬少妇毛片| 中文字幕国产亚洲2019| 成人午夜在线影视| 亚洲3p在线观看| 国产精品久久久久av电视剧| 91精品久久久久久久久久久| 亚洲午夜免费| 蜜桃日韩视频| 久久精品青草| 青青草视频在线免费播放| 日本欧美在线看| 日本wwww色| 国产三级三级三级精品8ⅰ区| 亚洲欧洲综合网| 性感美女极品91精品| 正在播放亚洲精品| 日韩精品一区二区三区四区视频 | 国产欧美一区二区精品性色超碰| 国产白丝一区二区三区| 一区二区三区欧美久久| 日本视频在线观看免费| 欧美乱熟臀69xxxxxx| 国模人体一区二区| 最近2019中文字幕第三页视频| 人人澡人人添人人爽一区二区| 欧美一级高清免费播放| 96sao精品免费视频观看| 久久99国产精品99久久| 五月婷婷亚洲| 欧美成人黑人猛交| 懂色av噜噜一区二区三区av| 久久久久久久久久久久| 一区二区三区四区精品在线视频 | 日韩一级成人av| 噜噜噜在线观看播放视频| 欧美尺度大的性做爰视频| 少妇一区视频| 国产精品一区二区av| 天天综合网91| 国产又大又黄又粗的视频| caoporn国产精品| 久久中文免费视频| 欧美日韩国产在线观看| 亚洲人成色777777精品音频| 欧美乱妇40p| 日韩专区视频| 水蜜桃一区二区三区| 国产精品久久久久久模特| 潘金莲一级淫片aaaaa| 亚洲丝袜制服诱惑| 激情网站在线观看| 亚洲欧美成人网| 国产精品电影| 99国产高清| 欧美a级在线| 亚洲高清av一区二区三区| 中文字幕日韩精品一区| 中文字幕 人妻熟女| 亚洲丝袜av一区| 婷婷午夜社区一区| 久久亚洲综合网| 亚洲欧美高清| 黄色性生活一级片| 日韩欧美一区二区三区| 亚洲aⅴ乱码精品成人区| 久久久久久网站| 风间由美一区二区av101| 成人午夜免费在线视频| 国产乱码字幕精品高清av| 欧美一级片在线视频| 欧美片网站yy| 看女生喷水的网站在线观看| 国产欧洲精品视频| 天天射天天综合网| 亚洲色图偷拍视频| 亚洲美女视频在线| 成人av无码一区二区三区| 欧美激情中文网| swag国产精品一区二区| 成人在线观看你懂的| 91老师片黄在线观看| 黄色片视频免费| 国产一区二区三区视频免费| 久久婷婷五月综合色丁香| 一区二区91美女张开腿让人桶| 久久99精品久久久久久| 一起操在线播放| 欧美va在线播放| 欧美男男tv网站在线播放| 日本在线成人一区二区| 美腿丝袜一区二区三区| 欧美激情图片小说| 亚洲精品一区二区精华| 看黄在线观看| 色一情一乱一伦一区二区三区丨 | 超碰国产在线观看| 国产欧美精品日韩精品| 欧美88av| 亚洲成人日韩在线| 欧美日韩高清一区二区不卡| 成人日韩欧美| 精品国产乱码久久久久久郑州公司| 免费视频一区二区三区在线观看| 娇妻被老王脔到高潮失禁视频| 欧美二区在线观看| 91白丝在线| 亚洲激情啪啪| 成人免费视频免费观看| 男人的天堂av网站| 欧美精品亚州精品| 男男gay无套免费视频欧美| gogogo高清免费观看在线视频| 一区二区三区在线免费| 女人偷人在线视频| 亚洲最大av在线| 老妇喷水一区二区三区| 国产一区二区播放| 亚洲三级av在线| 亚洲不卡在线| 日韩av片网站| 天天综合色天天综合色h| 免费看a在线观看| 精品一区二区三区日本| 国产一区 二区 三区一级|