这个问题相当麻烦,根据golang-nuts/google groups中的这篇文章,golang现在与将来都不会支持参数默认值。Go始终在使得自己变得尽可能的简单,而增加这种额外的支持会使parser变得更复杂。
设置参数值的好处:
但是参考资料中提到了几种实现默认值的方法:
- // 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)
- }
go的一大特点就是所有的变量都必须经过初始化。那如果在函数内部读取到参数值为初始化值,即可进行对应的操作。 但是这种方法无法解决设置参数默认值时所经常应对的场景,即参数缺省问题。
- // 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)
- }
上述方法中,a是必须的,而b是可选的。 此时b的默认值时5,如果b_optional中存在数据,则将其读取。
- // 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)
- }
虽然也能做到缺省参数(如果不设置A属性,则该属性将被默认初始化),但是这种方式只对字符串管用。
- 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)
- }
相当泛用的方法,但是对于不同的类型就不可行了。