groovy中具有默认值的命名参数

Posted

技术标签:

【中文标题】groovy中具有默认值的命名参数【英文标题】:named parameters with default values in groovy 【发布时间】:2013-08-02 20:13:49 【问题描述】:

是否可以在 groovy 中使用具有默认值的命名参数?我的计划是创建一种对象工厂,可以在没有参数的情况下调用它以获得具有默认值的对象。此外,我需要为对象显式设置任何参数的功能。例如,我相信这可以通过 Python 关键字参数实现。

我现在尝试使用的代码如下所示

// Factory method
def createFoo( name='John Doe', age=51, address='High Street 11') 
  return new Foo( name, age, address )


// Calls
Foo foo1 = createFoo()  // Create Foo with default values
Foo foo2 = createFoo( age:21 )  // Create Foo where age param differs from defaut
Foo foo3 = createFoo( name:'Jane', address:'Low Street 11' )  // You get the picture
// + any other combination available

我正在开发的实际应用程序将有更多的参数,因此需要更多的组合。

谢谢

更新:

我计划的工厂方法是用于测试目的。无法真正触及实际的 Foo 类,尤其是它的默认值。

下面的@dmahapatro 和@codelarks answere 很好地使用了 Map 作为参数,这让我对可能的解决方案有了一个想法。我可以使用所需的默认值创建一个映射并覆盖所需的值,然后将其传递给工厂方法。这可能会完成这项工作,我会继续这样做,除非我得到更好方法的提示。

我目前的方法如下

defaults = [ name:'john', age:61, address:'High Street']

@ToString(includeFields = true, includeNames = true)
class Foo 
  // Can't touch this :)
  def name = ''
  def age = 0
  def address = ''


def createFoo( Map params ) 
  return new Foo( params )


println createFoo( defaults )
println createFoo( defaults << [age:21] )
println createFoo( defaults << [ name:'Jane', address:'Low Street'] )

注意: leftShift 操作 (

【问题讨论】:

不要那样做。 defaults 在这种情况下保持状态。让它成为本地的。查看我的更新。 我确实意识到了这一点,因此在我的更新中添加了注释。无论如何,使用函数 local map 作为默认值是一种更好的方法。感谢您的提示。 【参考方案1】:

默认情况下,Groovy 会为您执行此操作(地图构造函数)。您不需要工厂方法。这是一个例子

import groovy.transform.ToString

@ToString(includeFields = true, includeNames = true)
class Foo
    String name = "Default Name"
    int age = 25
    String address = "Default Address" 


println new Foo()
println new Foo(name: "John Doe")
println new Foo(name: "Max Payne", age: 30)
println new Foo(name: "John Miller", age: 40, address: "Omaha Beach")

//Prints
Foo(name:Default Name, age:25, address:Default Address)
Foo(name:John Doe, age:25, address:Default Address)
Foo(name:Max Payne, age:30, address:Default Address)
Foo(name:John Miller, age:40, address:Omaha Beach)

更新 @codelark 的占星术 :)。如果无法访问该类以设置默认值,您可以这样做

@ToString(includeFields = true, includeNames = true)
class Bar
    String name
    int age
    String address


def createBar(Map map = [:])
    def defaultMap = [name:'John Doe',age:51,address:'High Street 11']
    new Bar(defaultMap << map)


println createBar()
println createBar(name: "Ethan Hunt")
println createBar(name: "Max Payne", age: 30)
println createBar(name: "John Miller", age: 40, address: "Omaha Beach")


//Prints
Bar(name:John Doe, age:51, address:High Street 11)
Bar(name:Ethan Hunt, age:51, address:High Street 11)
Bar(name:Max Payne, age:30, address:High Street 11)
Bar(name:John Miller, age:40, address:Omaha Beach)

【讨论】:

如果由于某种原因您不想使用地图构造函数,您可以像上面一样创建函数,但使用单个地图参数并完成同样的事情。 我用这些详细信息更新了我的问题,但我也会在此处为您添加它们。该方法用于测试目的,因此我无法触及实际 Foo 类的默认值。

以上是关于groovy中具有默认值的命名参数的主要内容,如果未能解决你的问题,请参考以下文章

Scala API中的选项和命名默认参数是不是像油和水?

参数定义的顺序必须是:必选参数默认参数可变参数命名关键字参数和关键字参数。

我可以在 Ruby 2.x 中要求命名参数吗?

具有显式默认命名空间的 XML 文档的 XPath 和命名空间规范

Python入门-5函数:06参数类型-位置参数-默认值参数-命名参数-可变参数-强制命名参数

Python函数中的必选/默认/可变/关键字/命名参数