Golang编程技巧:如何为函数参数添加默认值?

2023年 7月 11日 102.6k 0

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结构体。

这种方法仅适用于从包外部调用函数,而不适用于从包内部调用。

另一种选择是使用函数选项模式,它允许您将可变数量的选项作为参数传递给函数。这样可以更灵活,也更易于阅读,但也可能使代码更复杂。

函数选项模式

这种流行的模式在许多库中使用。在本节中,我将逐步介绍如何使用它:

  • 1. 创建一个结构体来保存我们的参数,包括两个字段:Name和Age。
  • type GreetingOptions struct {
        Name string
        Age  int
    }
  • 1. 现在让我们定义Greet函数,将我们的新结构体作为参数:
  • func Greet(options GreetingOptions) string {
        return "Hello, my name is " + options.Name + " and I am " + strconv.Itoa(options.Age) + " years old."
    }
  • 1. 这是一个有趣的部分,我们在结构体的字段中定义函数选项:
  • 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
        }
    }
  • 1. 使用我们的新类型 GreetingOption 创建一个包装器:
  • 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等等。

    总结

    总结一下,在函数参数中添加默认值是一种在代码中提供灵活性和便利性的有用方法。将默认值纳入到函数中可以成为您工具包中有价值的技巧。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论