利用Golang可选参数实现可选模式
创始人
2024-05-17 05:10:03
0

本文讨论Golang函数可选参数及函数类型,以及如何利用可选函数类型实现可选模式。同时通过构造函数作为示例,实现强大带可选参数的构造函数,让代码更直观、灵活、支持扩展。

从需求开始

可选参数给函数传递额外参数扩展或修改其行为,下面示例利用可选功能创建House类型:

h := NewHouse(WithConcrete(),WithoutFireplace(),
)

NewHouse是构造函数,WithConcreteWithoutFireplace是传入构造函数的可选参数,用于修改其返回值。下面会详细WithConcreteWithoutFireplace可选功能函数,有时它们比正常函数参数更有用。

定义构造函数

首先定义要利用可选功能的结构体:

type House struct {Material     stringHasFireplace boolFloors       int
}// `NewHouse` is a constructor function for `*House`
func NewHouse() *House {const (defaultFloors       = 2defaultHasFireplace = truedefaultMaterial     = "wood")h := &House{Material:     defaultMaterial,HasFireplace: defaultHasFireplace,Floors:       defaultFloors,}return h
}

House可能采用不同材料,有多层,并可能包括壁炉。NewHouse构造函数返回House指针,所有属性包括缺省值。正常情况下,首先构造House,然后根据不同需求修改属性值。使用函数可选参数,可以给构造函数传入一组修改器函数。

定义可选函数

首先定义函数类型,接受House类型指针:

type HouseOption func(*House)

这是可选函数的签名,下面定义一些可选函数用于修改*House实例:

func WithConcrete() HouseOption {return func(h *House) {h.Material = "concrete"}
}func WithoutFireplace() HouseOption {return func(h *House) {h.HasFireplace = false}
}

上面每个函数是可选构造函数,返回另一个函数,带*House参数,没有返回值。我们看到返回的函数修改了*House实例的属性。还可以实现其他可选函数类型用于修改参数实例属性,下面函数返回修改楼层的可选函数:

func WithFloors(floors int) HouseOption {return func(h *House) {h.Floors = floors}
}

增强构造函数

现在组合可选功能函数和构造函数:

// NewHouse now takes a slice of option as the rest arguments
func NewHouse(opts ...HouseOption) *House {const (defaultFloors       = 2defaultHasFireplace = truedefaultMaterial     = "wood")h := &House{Material:     defaultMaterial,HasFireplace: defaultHasFireplace,Floors:       defaultFloors,}// Loop through each optionfor _, opt := range opts {// Call the option giving the instantiated// *House as the argumentopt(h)}// return the modified house instancereturn h
}

构造函数接受一组任意数量可选功能函数作为参数,首次初始化House属性后,依此运行可选功能函数修改属性值。
回到开始的示例,现在可以实现带可选参数的构造函数调用:

h := NewHouse(WithConcrete(),WithoutFireplace(),WithFloors(3),
)

可选模式的优势

上面讨论了如何实现可选模式,这里总结下其优势。

直观清晰

相比于显示修改对象属性:

h := NewHouse()
h.Material = "concrete"

可利用构造函数直接实现:

h := NewHouse(WithConcrete())

采用这种方式更清晰,无需指定字符串值,避免打字错误并暴露*House内部细节。

支持扩展

可选模式支持扩展,总是支持不同可选函数参数传入构造函数。举例,既然房屋楼层可以为任何整数,我们提供具体数值作为参数传入构造函数:

h := NewHouse(WithFloors(4))

参数顺序

使用可选模式与参数顺序无关,相比于正常参数有很大的灵活性;而且,可以提供任意个可选参数,相比正常参数则必须提供所有参数。

// 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)

相关内容

热门资讯

金钱和势力一样重要吗? 金钱和势力一样重要吗?其实金钱和势力是因果关系的,因为有了金钱所以才会形旦悉成势力,因为有了势力,所...
我的女儿学习不自觉,不极极,我... 我的女儿学习不自觉,不极极,我应该怎样引导她?多大了,可以引导她让她以爱学习为乐趣陪她一起做作业,陪...
福建武夷学院怎么样 福建武夷学院怎么样福建武夷学院怎么样比去其他二本同等级的院校会好点,个人感觉还是爱校的呵呵整体来说不...
诗文中腊月通常是几月? 诗文中腊月通常是几月?腊月一般指的是农历十二月,就是临近春节那段时间。不是“腊月通常是几月”,是传承...
有没有人认为张丹峰很帅 有没有人认为张丹峰很帅真的很帅,不是都被称为暖男和“国民备胎了吗”。但是我个人认为超哥更帅
好多人都说学习机小牌子不能买,... 好多人都说学习机小牌子不能买,买就买万利达的,是这样吗?是,要不然没电太快
玩MC什么意思 玩MC什么意思玩MC什么意思游戏。中文叫我的世界。(看看我的小手艺)
求女朋友生日祝福语(藏头诗,祝... 求女朋友生日祝福语(藏头诗,祝符婷生日快乐)卿卿我我祝福愿,天赐良缘符地仙,美貌依旧婷婷立,天地人神...
薄薄的叶片像浅绿色的翡翠是什么... 薄薄的叶片像浅绿色的翡翠是什么修辞手法薄薄的叶片像浅绿色的翡翠是什么修辞手法是比喻手法。
死侍现在已经有几部了 死侍现在已经有几部了才出了一部,明年的暑假还会出第二部。
类似于《英雄联盟之谁与争锋》风... 类似于《英雄联盟之谁与争锋》风格的小说英雄联盟之传奇归来 英雄联盟之征途英雄联盟之极品天才
父子关系应该怎么维护呢?你有什... 父子关系应该怎么维护呢?你有什么看法?父子关系应该合理的维护,我觉得父子关系是非常重要的,也决定了孩...
急,关于仙剑2江宁府鼠仓的问题... 急,关于仙剑2江宁府鼠仓的问题!!我上了二楼后,一直在打老鼠,转圈圈,根本找不到第二条出路啊,打得我...
请问“好好学习”中的“好好”正... 请问“好好学习”中的“好好”正确读音?要标准答案,谢谢!都是三声.轻声发音不适合这个短语好字是hao...
哪有(前妻跟我回家)全文 哪有(前妻跟我回家)全文
雪人样子的句子! 雪人样子的句子!我非常喜欢雪。下雪的时候,天地间白茫茫的一片,走进雪里,就像走进洁白晶莹的世界。我喜...
基因突变会改变基因中嘌呤和嘧啶... 基因突变会改变基因中嘌呤和嘧啶的比值吗可能会也可能不会不会,都说了是基因,那么则是双链,A-T (腺...
中国近代谁写散文写得好呀 中国近代谁写散文写得好呀朱自清——孤寂感人梁实秋、周作人、宗白华、余秋雨等都很不错的。非朱自清莫属!...
堰塞湖的“堰”是什么意思? 堰塞湖的“堰”是什么意思?我想知道!!含有堤坝的意思。是指修筑在内河上的既能蓄水又能排水的小型水利工...
求穿越类小说完结的 类似与星神... 求穿越类小说完结的 类似与星神震天的就是说主人公一出现就是很强悍的那种!《九天剑仙在异界》