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.它在沒有編譯靜態的情況下工作,或者按照編譯動態的順序工作。
我把'void'來演示編譯靜態。通過刪除'='它將回到相同的實現。我修改了一下問題代碼(添加斷言)。 – exodream
嗯..我是否也需要重寫putAt方法來支持'+ ='和'Map'? – exodream
不,這個'putAt'方法在'map'對象上被調用,而不是在'MutableInt'上。我更新了我的答案,以顯示正在更新的地圖值 – Will