簡體   English   中英

在 Xtend 中的 Iterable object 的過濾器 function 中將多種類型作為參數傳遞

[英]Pass multiple types as parameter in filter function of Iterable object in Xtend

我正在使用 Xtext 的 DSL 生成器接口,以便基於我的 Xtext DSL 生成一些模型。 這工作正常,但現在我在編寫生成器時遇到了一些問題。 我正在使用生成器過濾掉在我的 Xtext DSL 中聲明的規則。 為此,我選擇某些規則,然后將它們轉換為Iterable object,然后我可以使用它來過濾某些類型(請參閱下面我的代碼中的toIterable.filter()部分)。 下面的代碼包含一個 for 循環,它本身又包含 3 個嵌套的 for 循環。 這些嵌套循環都過濾一種特定類型的方法語句(我在 DSL 中聲明的類型)。 我想通過將 3 種類型作為參數傳遞給filter()方法,將這 3 個 for 循環組合成一個 for 循環。 在這種情況下,會有一個嵌套的 for 循環,其中條件理想情況下看起來像:

for (eachMethodStatement : ifStatement.expression.eAllContents.toIterable.filter(StatementSort1, StatementSort2, StatementSort3)

問題是filter()方法只接受一個參數(一種類型),所以現在我必須編寫三個名為getDemand的調度方法,它們基本上都做同樣的事情。 它現在可以工作,但這迫使我為要過濾的每種類型編寫大量樣板代碼。

有沒有一種方法可以在不創建大量樣板代碼的情況下過濾多種類型(在一個 for 循環中)?

for (ifStatement : ifElseStatement.eAllContents.toIterable.filter(IfStatements)){
    for (persistenceFunction : ifStatement.expression.eAllContents.toIterable.filter(SingleLibraryPersistenceMethodStatement)) {
            expressionDemand += getDemand(persistenceFunction,resourceTable)                            
        }
    for (interfaceFunction : ifStatement.expression.eAllContents.toIterable.filter(SingleLibraryInterFaceMethodStatement)) {                    
            expressionDemand += getDemand(interfaceFunction,resourceTable)                          
        }
    for (businessFunction : ifStatement.expression.eAllContents.toIterable.filter(SingleLibraryBusinessMethodStatement)) {                  
            expressionDemand += getDemand(businessFunction,resourceTable)
        }
    for (persistenceFunction : ifStatement.expression.eAllContents.toIterable.filter(RelationalOperator)) {
            expressionDemand += getDemand(persistenceFunction,resourceTable)                            
        }
}

<T> T filter(Class<T>)不能做多種類型,因為返回類型不能是T但 - 在極端情況下Object必須稍后強制轉換。

但是:如果您的四種類型( SingleLibraryPersistenceMethodStatementSingleLibraryInterFaceMethodStatementSingleLibraryBusinessMethodStatementRelationalOperator )共享特定的接口或超類型,則可以將其與現有的filter()方法一起使用:

for (ifStatement : ifElseStatement.eAllContents.toIterable.filter(IfStatements)){
    for (statement : ifStatement.expression.eAllContents.toIterable.filter(Statement)) {
            expressionDemand += getDemand(statement,resourceTable)                          
    }
}
def Demand getDemand(Statement statement, ResourceTable resourceTable){
    ...
}

另一種解決方案是在這種情況下避免filter並使用帶有類型保護的switch ,如下所示:

for (ifStatement : ifElseStatement.eAllContents.toIterable.filter(IfStatements)){
    for (it : ifStatement.expression.eAllContents) {
        switch(it){
            SingleLibraryPersistenceMethodStatement,
            SingleLibraryPersistenceMethodStatement,
            SingleLibraryBusinessMethodStatement:
                 expressionDemand += getDemand(it,resourceTable)
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM