Возникли проблемы с созданием объектов специального типа для Groovy - PullRequest
0 голосов
/ 10 января 2019

Когда вы начинаете использовать обработку gpath для коллекций в groovy, то, какой именно тип структуры данных вы имеете дело, может несколько запутать (по крайней мере, для меня) - обычно в 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 был «преобразован» в 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 вместо таблицы (и в любом случае, вероятно, потребуется явное преобразование «как»)

Обновление - я только что сделал метод "исправления" в GroupedTable, который, кажется, решает проблему, но неуклюж!

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

1 Ответ

0 голосов
/ 14 января 2019

Я не знаю, почему не работает автоматическое преобразование типов

однако, вы можете @Override метод groupBy, подобный этому:

(Edit by billk - так я реализовал предложение Даггетта)

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. Я, вероятно, уберу их и сделаю из них больше полезных классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...