如何处理 `New(...` 函数中的长参数列表
How to deal with long parameter lists in `New(...` functions
假设我有一个名为 MyStruct
的本地化结构,其主体如下:
struct MyStruct {
myField1 string
myField2 string
myField3 string
...
myFieldN string
}
以及一个为外部调用者实例化新 MyStruct
s 的函数:
func NewMyStruct(myField1, myField2, myField3, ..., myFieldN string) MyStruct {
return MyStruct{
myField1: myField1,
myField2: myField2,
myField3: myField3,
...
myFieldN: myFieldN,
}
}
问题:我如何最好地处理结构中有太多字段导致 NewMyStruct(...
函数 way[=26= 的情况] 参数太多? 是否有缓解此问题的最佳做法?截至目前,我的代码库中有几个这样的函数:
func NewSuperStruct(myField1, myField2, myField3, myField4, myField5, myField6, myField7, myField8, myField9, myField10, myField11, myField12, myField13, myField14, myField15, myField16, myField17, myField18, myField19, myField20, myField21, myField22) ...
但在 properties/fields 不属于其中的意义上,结构本身不一定是无意义的,在我的应用程序中它们确实有意义,结构太大了,仅此而已。
就个人而言(显然取决于结构的目标)我是功能选项的忠实粉丝:
type MyStructOpts func(*MyStruct)
func WithField1(field1 string) MyStructOps {
return func(m *MyStruct) {
m.myField1 = field1
}
}
func New(opts ...MyStructOpts) *MyStruct {
m := MyStruct{
myField1: "someDefaultIfneeded",
}
for _, opt := range opts {
opt(&m)
}
return &m
}
可以如下使用:
New(
WithField1("someString"),
...
)
这有两个好处:
- new的调用者不用担心顺序
- 通过字段名称显式传递值,这意味着您不会混淆 Field1 和 Field2
- 您可以将不同的默认值传递给
MyStruct
,以防调用者不传递 WithField1
- 添加更多字段不会导致必须更新
New
的所有调用方
我会说只是没有 New
func:
struct MyStruct {
myField1 string
myField2 string
myField3 string
}
val := MyStruct{
myField1: "one",
myField2: "two",
myField3: "three",
}
如果需要从另一个包设置未导出的字段,请使用某种选项或配置:
type MyStruct struct {
Exported string
unexported string
}
type MyStructOptions struct {
Exported string
Unexported string
}
func NewMyStruct(opts MyStructOptions) *MyStruct {
return &MyStruct{
Exported: opts.Exported,
unexported: opts.Unexported,
}
}
假设我有一个名为 MyStruct
的本地化结构,其主体如下:
struct MyStruct {
myField1 string
myField2 string
myField3 string
...
myFieldN string
}
以及一个为外部调用者实例化新 MyStruct
s 的函数:
func NewMyStruct(myField1, myField2, myField3, ..., myFieldN string) MyStruct {
return MyStruct{
myField1: myField1,
myField2: myField2,
myField3: myField3,
...
myFieldN: myFieldN,
}
}
问题:我如何最好地处理结构中有太多字段导致 NewMyStruct(...
函数 way[=26= 的情况] 参数太多? 是否有缓解此问题的最佳做法?截至目前,我的代码库中有几个这样的函数:
func NewSuperStruct(myField1, myField2, myField3, myField4, myField5, myField6, myField7, myField8, myField9, myField10, myField11, myField12, myField13, myField14, myField15, myField16, myField17, myField18, myField19, myField20, myField21, myField22) ...
但在 properties/fields 不属于其中的意义上,结构本身不一定是无意义的,在我的应用程序中它们确实有意义,结构太大了,仅此而已。
就个人而言(显然取决于结构的目标)我是功能选项的忠实粉丝:
type MyStructOpts func(*MyStruct)
func WithField1(field1 string) MyStructOps {
return func(m *MyStruct) {
m.myField1 = field1
}
}
func New(opts ...MyStructOpts) *MyStruct {
m := MyStruct{
myField1: "someDefaultIfneeded",
}
for _, opt := range opts {
opt(&m)
}
return &m
}
可以如下使用:
New(
WithField1("someString"),
...
)
这有两个好处:
- new的调用者不用担心顺序
- 通过字段名称显式传递值,这意味着您不会混淆 Field1 和 Field2
- 您可以将不同的默认值传递给
MyStruct
,以防调用者不传递WithField1
- 添加更多字段不会导致必须更新
New
的所有调用方
我会说只是没有 New
func:
struct MyStruct {
myField1 string
myField2 string
myField3 string
}
val := MyStruct{
myField1: "one",
myField2: "two",
myField3: "three",
}
如果需要从另一个包设置未导出的字段,请使用某种选项或配置:
type MyStruct struct {
Exported string
unexported string
}
type MyStructOptions struct {
Exported string
Unexported string
}
func NewMyStruct(opts MyStructOptions) *MyStruct {
return &MyStruct{
Exported: opts.Exported,
unexported: opts.Unexported,
}
}