Groovy命名和默认参数

时间:2011-09-14 11:23:01

标签: groovy arguments argument-passing

Groovy支持默认和命名参数。我只是看不到他们一起工作。

我需要一些类来支持使用简单的非命名参数进行构造,并使用如下所示的命名参数:

def a1 = new A(2)
def a2 = new A(a: 200, b: "non default")

class A extends SomeBase {
    def props
    A(a=1, b="str") { 
        _init(a, b)
    }

    A(args) { 
       // use the values in the args map:
       _init(args.a, args.b)
       props = args
    }

    private _init(a, b) {
    }

}

同时支持两者通常是一种好习惯吗?上面的代码是唯一的方法吗?

1 个答案:

答案 0 :(得分:6)

给定的代码会导致一些问题。特别是,它将生成两个带有单个Object参数的构造函数。第一个构造函数生成等效于:

的字节码
A() // a,b both default
A(Object) // a set, b default
A(Object, Object) // pass in both

第二个产生这个:

A(Object) // accepts any object

您可以通过添加一些类型来解决此问题。尽管groovy具有动态类型,但方法和构造函数中的类型声明仍然很重要。例如:

A(int a = 1, String b = "str") { ... }
A(Map args) { ... }

至于良好做法,我只使用其中一个groovy.transform.Canonicalgroovy.transform.TupleConstructor注释。它们将自动提供正确的属性映射和位置参数构造函数。 TupleConstructor仅提供构造函数,Canonical应用了与equalshashCodetoString相关的一些其他最佳实践。