2013-08-01 63 views
15

在groovy中可以使用默認值命名參數嗎?我的計劃是製作一種對象工廠,爲了獲得具有默認值的對象,可以根本不調用任何參數。此外,我需要的功能顯式設置對象的任何參數。例如,我相信這對Python關鍵字參數是可能的。在groovy中使用默認值命名參數

我試圖用現在的代碼是一樣的東西下面

// 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 

是我的工作會有的參數有更多的真正的應用程序,從而有更多的組合需要。

感謝

UPDATE:

工廠方法我計劃是用於測試目的。無法真正觸及實際的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操作(< <)修改了原來的地圖,所以在上面的例子中年齡將是最後的方法調用21爲好。在我的情況下,這不是一個問題,因爲每次在安裝方法中都可以新建默認值映射。

+0

不這樣做。在這種情況下,'defaults'保持狀態。使其成爲本地。查看我的更新。 – dmahapatro

+0

我確實意識到這一點,因此我的更新中的筆記。無論如何,使用函數本地地圖作爲默認值是一種更好的方法。謝謝你的提示。 – kaskelotti

回答

22

默認情況下,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) 

UPDATE
@ 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) 
+3

,如果由於某種原因你不想使用地圖構造函數,你可以像上面那樣創建函數,但是隻需要一個地圖參數並且完成同樣的事情。 – codelark

+1

我用這些細節更新了我的問題,但我也會在這裏爲您添加它們。該方法用於測試目的,所以我無法觸及實際Foo類的默認值。 – kaskelotti