创建用于Groovy的特殊类型对象时遇到一些问题

时间:2019-01-10 18:47:44

标签: groovy syntax type-conversion

当您开始对groovy中的集合使用gpath处理时,您正在处理的数据类型的确切类型可能会让人感到困惑(至少对我而言)-通常在groovy中,您仅使用“ Duck type”(鸭子类型),一切正常,但是Duck Typing实际上会损害编码人员对变量在任何时间点可能包含的内容的理解。

为了保持直率,我开始将变量作为类型进行分解以提高理解。但是,这些类型非常隐秘且无益:

Map<String, List<Map<String, String>>> 

实际上是一个非常常见的(并且非常有用的)中间结构,但是在代码中查看它的人并没有真正的帮助。 (如果不明显,它的行为很像一个索引/分组SQL表,我敢打赌它不是)

在向同事解释我的代码(并试图自己理解它)的同时,我创建了一些新类型来更清楚地说明我的意图:

class Row extends LinkedHashMap<String, String>{}    // Record--like a row in a table
class Table extends ArrayList<Row>{}                 // A table--like an SQL table.  A list of rows    
class GroupedTable extends LinkedHashMap<String, Table> // A map of tables indexed by some name using groupBy()

这出奇地好。定义完这些之后,我可以说些类似的话:

Table t=sql.rows(someQuery) as Table
Row r=t.get(0)
GroupedTable grouped= t.groupBy{it.an_sql_column} as GroupedTable

有时我不必手动强制值(如在行中),有时我却要强制(如GroupedTable中),这有点令人困惑,但它通常可以工作(即使打开了@TypeChecked)

我最大的困惑是,即使将分组“转换”为GroupedTable,该闭包签名也不起作用:

grouped.collect{String modelName, Table subTable->…}

它会在运行时中断,因为即使我使用“ as GroupedTable”转换了分组对象,它也没有将groupBy返回的值从LinkedLists转换为表。

如果我使用闭包签名,它会起作用:

grouped.collect{String modelName, LinkedList subTable->…}

,但其他所有地方似乎都能自动转换。我尝试将“,subTable as Table”指定为“”,但这对于闭包而言无效。

所以我想知道是否有一种方法可以提供从LinkedList到表的“自动”转换,还是可以轻松地处理GroupedTable使其包含值而不是LinkedLists的表

一小部分自动转换可以使Row,Table和GroupedTable更加顺畅地工作,这是我理想的解决方案,但是我不认为asType()会这样做,因为我需要将其应用于LinkedList而不是表格(无论如何,它可能都需要显式的“ as”转换。)

更新-我刚刚在GroupedTable中制作了一个“修复”方法,该方法似乎可以解决问题,但是笨拙!

def fix(){keyset().each{put(it, get(it) as Table)}}

1 个答案:

答案 0 :(得分:1)

我不知道为什么自动类型转换不起作用

但是,您可以@Override这样的groupBy方法:

(比尔克编辑-这就是我实施达格特的建议的方式)

class Table extends ArrayList<Row> {
    GroupedTable groupBy(Closure closure)
    def gt=DefaultGroovyMethods.groupBy(this as Iterable, closure) as GroupedTable
    gt.changeTypeOfAllValuesToTable()
    return gt

    static Table build(Iterable list){
        return list.collect{it as Row} as Table
    }
}

class GroupedTable extends LinkedHashMap<String, Table> {
    GroupedTable changeTypeOfAllValuesToTable()
    this.keySet().each{String k->
        Table t=Table.build(get(k))
        put(k, t)
        return this
}

稍加努力(如果有人感兴趣的话,可以发布它),我将所有这些都与@TypeChecked注释一起使用。我可能会清理它们,并从中制作出更多有用的类。