在Go语言中,有没有一种方法可以指定函数的默认值?我正在查找文档,但无法找到任何指定这种可能性的内容。
func SaySomething(i string = "Hello")(string){
...
}
在Go语言中,有没有一种方法可以指定函数的默认值?我正在查找文档,但无法找到任何指定这种可能性的内容。
func SaySomething(i string = "Hello")(string){
...
}
不过还有其他选项可以实现默认值。这方面有一些优秀的博客文章,但是这里提供了一些具体的例子。
选项1:调用者选择使用默认值
// Both parameters are optional, use empty string for default value
func Concat1(a string, b int) string {
if a == "" {
a = "default-a"
}
if b == 0 {
b = 5
}
return fmt.Sprintf("%s%d", a, b)
}
选项2:在末尾的一个可选参数
// a is required, b is optional.
// Only the first value in b_optional will be used.
func Concat2(a string, b_optional ...int) string {
b := 5
if len(b_optional) > 0 {
b = b_optional[0]
}
return fmt.Sprintf("%s%d", a, b)
}
选项3:一个配置结构体
// A declarative default value syntax
// Empty values will be replaced with defaults
type Parameters struct {
A string `default:"default-a"` // this only works with strings
B string // default is 5
}
func Concat3(prm Parameters) string {
typ := reflect.TypeOf(prm)
if prm.A == "" {
f, _ := typ.FieldByName("A")
prm.A = f.Tag.Get("default")
}
if prm.B == 0 {
prm.B = 5
}
return fmt.Sprintf("%s%d", prm.A, prm.B)
}
选项4:完全的可变参数解析(类似JavaScript)
func Concat4(args ...interface{}) string {
a := "default-a"
b := 5
for _, arg := range args {
switch t := arg.(type) {
case string:
a = t
case int:
b = t
default:
panic("Unknown argument")
}
}
return fmt.Sprintf("%s%d", a, b)
}
不,没有办法指定默认值。我认为这是有意而为之的,以增强可读性,代价是写作人需要更多的时间(和希望思考)。
我认为拥有“默认值”的正确方法是编写一个新函数,该函数向更通用的函数提供该默认值。通过这样做,您的代码在显示意图方面变得更加清晰。例如:
func SaySomething(say string) {
// All the complicated bits involved in saying something
}
func SayHello() {
SaySomething("Hello")
}
我轻而易举地编写了一个函数来完成常见任务,并重复使用了通用函数。你可以在许多库中看到这一点,例如 fmt.Println
只是在原本 fmt.Print
的基础上添加了一个换行符。然而,在阅读他人代码时,通过调用的函数清楚地知道他们想要做什么。使用默认值时,如果不去参考函数的默认值,我将不知道应该发生什么。
func SaySomething(msg string = "Hello") string {
return fmt.Sprintf("I say %q", msg)
}
type SomethingSayer struct {
msg string
}
SaySomething
转化为结构体 SomethingSayer
上的方法。原来的函数参数 msg
被替换为 s.msg
,即 SomethingSayer
的一个字段:func (s SomethingSayer) SaySomething() string {
return fmt.Sprintf("I say %q", s.msg)
}
SomethingSayer
结构定义一个构造函数。这将使用原始的默认参数设置字段 msg
:func NewSaySomethingSayer() SomethingSayer {
return SomethingSayer {
msg: "Hello", // the default argument
}
}
func SaySomething() string {
return NewSaySomethingSayer().SaySomething()
}
SaySomething()
。如果不是这种情况,它仍然可以构建自己的 SomethingSayer
,然后调用 SaySomething()
方法:fmt.Println(SaySomething()) // I say "Hello"
s := SomethingSayer {
msg: "Bye",
}
fmt.Println(s.SaySomething()) // I say "Bye"
http.Get
、http.Head
和http.Post
中也遵循了这种方法。也就是说,此函数允许您执行GET请求而无需显式构造http.Client
:它使用全局可用的http.Client
值(http.DefaultClient
)并调用其上的Get
方法。同样,客户端代码仍然可以通过构造自己的http.Client
并在其上调用Get
来覆盖默认参数(例如超时)。
func Concat1(a string = 'foo', b int = 10) string {
,这将使任何给定的示例几乎只需要一行代码就能完成。 - Rotareti