Groovy: метод не может быть применен к (захват‹?›)

Я играю со статической проверкой типов Groovy и столкнулся с интересной проблемой. У меня есть метод Groovy, вызывающий метод Java. На стороне Groovy у меня есть

import com.restfb.Parameter
import com.restfb.Connection
import com.restfb.Version
import com.restfb.DefaultFacebookClient

@TypeChecked
static List<Map<String, String>> getPages(accessToken, query) {
    Connection<Page> conn = new DefaultFacebookClient(accessToken, Version.VERSION
public static Map<String, String> page2map(Page page) {
    Map<String, String> res = new HashMap<>();
    res.put("likes", page.getName());
    // some more stuff here
    return res;
}
5).fetchConnection( "search", Page.class, Parameter.with("q", query), Parameter.with("type", "page"), Parameter.with("fields", "name,about"), Parameter.with("limit", 100) ); conn.data.flatten().collect { p -> page2map(p) } // error here }

На стороне Java у меня есть

public static Map<String, String> page2map(Page page) {
    Map<String, String> res = new HashMap<>();
    res.put("likes", page.getName());
    // some more stuff here
    return res;
}

Без проверки типов этот код работает нормально. При проверке типов я получаю ошибку компилятора method cannot be applied to (capture<?>) в последней строке кода Groovy. Я использую Groovy 2.4.6. Какие-либо предложения?


person mbatchkarov    schedule 11.04.2016    source источник
comment
попробуйте определить тип p явно: .collect { Page p -> ... }   -  person injecteer    schedule 12.04.2016


Ответы (1)


Groovy по умолчанию и предполагает, что вы слишком универсальны. Это застало меня врасплох при попытке поговорить с Java.

Я подозреваю, что flatten или collect дает вам ArrayList или HashMap. Это встроенное замыкание может возвращать Object.

Поскольку вы явно не указываете, что возвращает collect, я ожидаю, что он вернет ArrayList<Object>, а встроенное закрытие будет иметь сигнатуру Object f(Object x).

Попробуйте быть предельно откровенным с (примерно) следующим

Map<String, String> my_method(Page p) = { return page2map(p) }
List<Map<String, String>> container;
container = conn.data.flatten().collect(my_method)
return container

Я бы также посмотрел на сгенерированные заводные заглушки, чтобы лучше понять, что происходит, чтобы увидеть, какие именно типы перебрасываются. Замыкание, которое вы используете, будет выглядеть примерно так: TheClass$getPages$Inline$Closure$1

Вы также можете рассмотреть возможность использования @TypeChecked, так как отсутствие необходимости иметь дело с типами является преимуществом использования Groovy в первую очередь.

Кроме того, вы можете иметь в виду ClassName.page2map, а не page2map

person Everspace    schedule 12.04.2016