Go语言没有默认参数值而感到沮丧?好消息是,你并不孤单!这个令人讨厌的限制会让你的代码更加繁琐,难以阅读。
每次都需要写额外的代码来检查参数是否提供,并在没有提供时使用默认值。
别担心!有办法绕过这个限制,在你的Go函数中添加默认值。当然,这可能没有内置的方式方便,但至少你不必一直携带那把象征性的雨伞。
简单的包装器
一种方法是定义一个包装函数,它使用参数的默认值来调用原始函数。
如果客户端没有指定名称,那么默认名称为"Jack"。下面是使用包装器的示例:
func greet(name string) string {
return "Hello, " + name
}
func greetWithDefaultJack(name string) string {
if name == "" {
name = "Jack"
}
return greet(name)
}
// you can have more than 1 default set
func greetWithDefaultJohn(name string) string {
if name == "" {
name = "John"
}
return greet(name)
}
通过这种方式,你可以在不修改greet函数内部任何代码的情况下设置greet的默认值。
“但这对于一个简单的函数来说太麻烦了吧?”
这可能是一个缺点,因为它需要你编写额外的代码,可能会使你的代码更难阅读。
隐藏你的参数
我们可以将函数的参数放在一个非导出的结构体中,让客户端根据需要初始化参数:
type greetingArguments struct {
Name string
Age int
}
func GreetingArguments() greetingArguments {
return greetingArguments{
Name: "Jack",
Age: 30,
}
}
现在让我们定义我们的Greet函数:
func Greet(options greetingArguments) string {
return "Hello, my name is " + options.Name + " and I am " + strconv.Itoa(options.Age) + " years old."
}
每次客户端想要使用Greet函数时,他们必须使用GreetingArguments()
函数创建一个greetingArguments
结构体。
这种方法仅适用于从包外部调用函数,而不适用于从包内部调用。
另一种选择是使用函数选项模式,它允许您将可变数量的选项作为参数传递给函数。这样可以更灵活,也更易于阅读,但也可能使代码更复杂。
函数选项模式
这种流行的模式在许多库中使用。在本节中,我将逐步介绍如何使用它:
type GreetingOptions struct {
Name string
Age int
}
func Greet(options GreetingOptions) string {
return "Hello, my name is " + options.Name + " and I am " + strconv.Itoa(options.Age) + " years old."
}
type GreetingOption func(*GreetingOptions)
func WithName(name string) GreetingOption {
return func(o *GreetingOptions) {
o.Name = name
}
}
func WithAge(age int) GreetingOption {
return func(o *GreetingOptions) {
o.Age = age
}
}
func GreetWithDefaultOptions(options ...GreetingOption) string {
opts := GreetingOptions{
Name: "Jack",
Age: 30,
}
for _, o := range options {
o(&opts)
}
return Greet(opts)
}
GreetWithDefaultOptions
函数为 GreetingOptions
结构体的 Name
(默认为“Jack”)和 Age
(默认为30)字段设置默认值,然后将传递的选项作为参数应用于该结构体。
最后,它使用修改后的结构体作为参数调用 Greet
函数。
要使用此代码,您可以使用要自定义的选项调用 GreetWithDefaultOptions
函数:
greeting := GreetWithDefaultOptions(WithName("Alice"), WithAge(20))
// "Hello, my name is Alice and I am 20 years old."
许多库都使用了函数选项模式,包括mongodb、aws-sdk-go、gorm、cli等等。
总结
总结一下,在函数参数中添加默认值是一种在代码中提供灵活性和便利性的有用方法。将默认值纳入到函数中可以成为您工具包中有价值的技巧。