代码之家  ›  专栏  ›  技术社区  ›  Bill K

在为groovy创建特殊类型对象时遇到一些问题

  •  0
  • Bill K  · 技术社区  · 7 年前

    当您开始在groovy中对集合使用gpath处理时,您所处理的数据结构的确切类型可能会有点混乱(至少对我来说)——通常在groovy中您只使用“Duck-typing”,一切都可以正常工作,但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)

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

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

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

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

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

    我的理想解决方案是使用一小部分自动转换,使行、表和GroupedTable工作得更顺畅,但我认为asType()无法做到这一点,因为我需要将其应用于LinkedList而不是Table(而且可能无论如何都需要显式的“as”转换)

    更新——我刚刚在GroupedTable中创建了一个“修复”方法,它似乎可以修复问题,但很笨拙!

    def fix(){keyset().each{put(it, get(it) as Table)}}
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Bill K    7 年前

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

    然而,你可以 @Override 这个 groupBy

    (billk编辑——这就是我如何实施Daggett的建议)

    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
    }