教你利用Golang可選參數(shù)實(shí)現(xiàn)可選模式
本文討論Golang函數(shù)可選參數(shù)及函數(shù)類型,以及如何利用可選函數(shù)類型實(shí)現(xiàn)可選模式。同時(shí)通過構(gòu)造函數(shù)作為示例,實(shí)現(xiàn)強(qiáng)大帶可選參數(shù)的構(gòu)造函數(shù),讓代碼更直觀、靈活、支持?jǐn)U展。
從需求開始
可選參數(shù)給函數(shù)傳遞額外參數(shù)擴(kuò)展或修改其行為,下面示例利用可選功能創(chuàng)建House類型:
h := NewHouse( WithConcrete(), WithoutFireplace(), )
NewHouse是構(gòu)造函數(shù),WithConcrete和WithoutFireplace是傳入構(gòu)造函數(shù)的可選參數(shù),用于修改其返回值。下面會(huì)詳細(xì)WithConcrete和WithoutFireplace可選功能函數(shù),有時(shí)它們比正常函數(shù)參數(shù)更有用。
定義構(gòu)造函數(shù)
首先定義要利用可選功能的結(jié)構(gòu)體:
type House struct {
Material string
HasFireplace bool
Floors int
}
// `NewHouse` is a constructor function for `*House`
func NewHouse() *House {
const (
defaultFloors = 2
defaultHasFireplace = true
defaultMaterial = "wood"
)
h := &House{
Material: defaultMaterial,
HasFireplace: defaultHasFireplace,
Floors: defaultFloors,
}
return h
}House可能采用不同材料,有多層,并可能包括壁爐。NewHouse構(gòu)造函數(shù)返回House指針,所有屬性包括缺省值。正常情況下,首先構(gòu)造House,然后根據(jù)不同需求修改屬性值。使用函數(shù)可選參數(shù),可以給構(gòu)造函數(shù)傳入一組修改器函數(shù)。
定義可選函數(shù)
首先定義函數(shù)類型,接受House類型指針:
type HouseOption func(*House)
這是可選函數(shù)的簽名,下面定義一些可選函數(shù)用于修改*House實(shí)例:
func WithConcrete() HouseOption {
return func(h *House) {
h.Material = "concrete"
}
}
func WithoutFireplace() HouseOption {
return func(h *House) {
h.HasFireplace = false
}
}上面每個(gè)函數(shù)是可選構(gòu)造函數(shù),返回另一個(gè)函數(shù),帶*House參數(shù),沒有返回值。我們看到返回的函數(shù)修改了*House實(shí)例的屬性。還可以實(shí)現(xiàn)其他可選函數(shù)類型用于修改參數(shù)實(shí)例屬性,下面函數(shù)返回修改樓層的可選函數(shù):
func WithFloors(floors int) HouseOption {
return func(h *House) {
h.Floors = floors
}
}增強(qiáng)構(gòu)造函數(shù)
現(xiàn)在組合可選功能函數(shù)和構(gòu)造函數(shù):
// NewHouse now takes a slice of option as the rest arguments
func NewHouse(opts ...HouseOption) *House {
const (
defaultFloors = 2
defaultHasFireplace = true
defaultMaterial = "wood"
)
h := &House{
Material: defaultMaterial,
HasFireplace: defaultHasFireplace,
Floors: defaultFloors,
}
// Loop through each option
for _, opt := range opts {
// Call the option giving the instantiated
// *House as the argument
opt(h)
}
// return the modified house instance
return h
}構(gòu)造函數(shù)接受一組任意數(shù)量可選功能函數(shù)作為參數(shù),首次初始化House屬性后,依此運(yùn)行可選功能函數(shù)修改屬性值。
回到開始的示例,現(xiàn)在可以實(shí)現(xiàn)帶可選參數(shù)的構(gòu)造函數(shù)調(diào)用:
h := NewHouse( WithConcrete(), WithoutFireplace(), WithFloors(3), )
可選模式的優(yōu)勢(shì)
上面討論了如何實(shí)現(xiàn)可選模式,這里總結(jié)下其優(yōu)勢(shì)。
直觀清晰
相比于顯示修改對(duì)象屬性:
h := NewHouse() h.Material = "concrete"
可利用構(gòu)造函數(shù)直接實(shí)現(xiàn):
h := NewHouse(WithConcrete())
采用這種方式更清晰,無需指定字符串值,避免打字錯(cuò)誤并暴露*House內(nèi)部細(xì)節(jié)。
支持?jǐn)U展
可選模式支持?jǐn)U展,總是支持不同可選函數(shù)參數(shù)傳入構(gòu)造函數(shù)。舉例,既然房屋樓層可以為任何整數(shù),我們提供具體數(shù)值作為參數(shù)傳入構(gòu)造函數(shù):
h := NewHouse(WithFloors(4))
參數(shù)順序
使用可選模式與參數(shù)順序無關(guān),相比于正常參數(shù)有很大的靈活性;而且,可以提供任意個(gè)可選參數(shù),相比正常參數(shù)則必須提供所有參數(shù)。
// What `NewHouse` would look like if we used
// regular function arguments
// We would always need to provide all three
// arguments no matter what
h := NewHouse("concrete", 5, true)到此這篇關(guān)于利用Golang可選參數(shù)實(shí)現(xiàn)可選模式的文章就介紹到這了,更多相關(guān)Golang可選參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang struct擴(kuò)展函數(shù)參數(shù)命名警告解決方法
今天在使用VSCode編寫golang代碼時(shí),定義一個(gè)struct,擴(kuò)展幾個(gè)方法,需要的朋友可以參考下2017-02-02
Golang中函數(shù)(Function)和方法(Method)的區(qū)別詳解
在Golang中,大家必然會(huì)頻繁使用到函數(shù)(Function)和方法(Method),但是有的同學(xué)可能并沒有注意過函數(shù)和方法的異同點(diǎn),函數(shù)和方法都是用來執(zhí)行特定任務(wù)的代碼塊,雖然很相似,但也有很大的區(qū)別,所以本文將詳細(xì)講解函數(shù)和方法的定義以及它們的異同點(diǎn)2023-07-07
Golang實(shí)現(xiàn)Trie(前綴樹)的示例
本文主要介紹了Golang實(shí)現(xiàn)Trie(前綴樹)的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01
Gin+Gorm實(shí)現(xiàn)增刪改查的示例代碼
本文介紹了如何使用Gin和Gorm框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單的增刪改查(CRUD)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12
Golang的os標(biāo)準(zhǔn)庫中常用函數(shù)的整理介紹
這篇文章主要介紹了Go語言的os標(biāo)準(zhǔn)庫中常用函數(shù),主要用來實(shí)現(xiàn)與操作系統(tǒng)的交互功能,需要的朋友可以參考下2015-10-10

