2015-07-20 62 views
0

在Groovy中,我可以重載運算符「+」加如下:Groovy - 如何在編譯爲靜態的Map中重載'+ ='運算符?

class MutableInt { 
    int val 

    MutableInt(int val) { this.val = val } 

    MutableInt plus(int val) {      
    return new MutableInt(this.val += val) 
    } 
} 

以上級工作正常,下面的測試情況:

def m1 = new MutableInt(1); 
assert (m1 + 1).val == 2; 

但是,如果我需要使用它在一起與Map像這樣與靜態

@groovy.transform.CompileStatic 
void compileItWithStatic() { 
    Map<Long, MutableInt> mutMap = [:].withDefault{ new MutableInt(0) } 
    assert (mutMap[1L] += 20).val == 20; 
} 
compileItWithStatic() 

編譯它我得到錯誤:

*Script1.groovy: 17: [Static type checking] - 
Cannot call <K,V> java.util.Map <java.lang.Long, MutableInt>#putAt(java.lang.Long, MutableInt) with arguments [long, int]*  

如何覆蓋'+ ='運算符並使用static進行編譯而不出錯?

編輯:

如果我做這樣沒有編譯靜態正常工作:

def m1 = new MutableInt(1); 
assert (m1 += 1).val == 2 // <----- caution: '+=' not '+' as in previous case 

但是,如果是這樣的方法中:

@groovy.transform.CompileStatic 
void compileItWithStatic_2() { 
    def m1 = new MutableInt(1); 
    assert (m1 += 1).val == 2 
} 

錯誤將是:

Script1.groovy: -1: Access to java.lang.Object#val is forbidden @ line -1, column -1. 
1 error 

P.S.它在沒有編譯靜態的情況下工作,或者按照編譯動態的順序工作。

回答

1

賦值部分拋出錯誤。一個簡單的+作品:

class MutableInt { 
    int val 

    MutableInt(int val) { this.val = val } 

    MutableInt plus(int val) {      
    return new MutableInt(this.val += val) 
    } 
} 

def m1 = new MutableInt(1); 
assert (m1 + 1).val == 2; 


@groovy.transform.CompileStatic 
def compileItWithStatic() { 
    Map<Long, MutableInt> mutMap = [:].withDefault{ new MutableInt(0) } 
    mutMap[1L] + 20 
    mutMap 
} 

assert compileItWithStatic()[1L].val == 20 

的Groovy是解析mutMap[1L] += 20mutMap.putAt(1L, 20)。這看起來像是一個bug。這工作:mutMap[1L] = mutMap[1L] + 20,儘管更詳細。


編輯:第二誤差似乎與表達(m1 + 1)被解析爲Object的結果。這應該工作:

@groovy.transform.CompileStatic 
void compileItWithStatic_2() { 
    def m1 = new MutableInt(1) + 1; 
    assert m1.val == 2 
} 
+0

我把'void'來演示編譯靜態。通過刪除'='它將回到相同的實現。我修改了一下問題代碼(添加斷言)。 – exodream

+0

嗯..我是否也需要重寫putAt方法來支持'+ ='和'Map'? – exodream

+0

不,這個'putAt'方法在'map'對象上被調用,而不是在'MutableInt'上。我更新了我的答案,以顯示正在更新的地圖值 – Will