Kotlin: Общая функция как возвращаемый тип?

В Котлине можно объявить общий тип функции как возвращаемый тип функции?

То, что я хочу достичь, будет выглядеть так на Java:

interface Factory { static Factory INSTANCE = new FactoryImpl(); <T> T create(String name, Class<T> type); } class PrefixedFactory implements Factory { private final String prefix; PrefixedFactory(String prefix) { this.prefix = prefix; } @Override public <T> T create(String name, Class<T> type) { return Factory.INSTANCE.create(prefix + name, type); } } 

(Обратите внимание, что в примере я обращаюсь к экземпляру Factory с использованием статического поля, чтобы избежать передачи общей функции в качестве параметра, что могло бы представлять свои проблемы в Котлине). Я хотел бы преобразовать префикс в функцию kotlin, но, как представляется, невозможно объявить общую функцию как возвращаемый тип:

 fun prefixer(prefix: String): <T> (String, KClass<T>) -> T { TODO() } 

Это, конечно, не компилируется. Мне кажется, что это ограничение по сравнению с функциональными интерфейсами Java. Есть ли способ сделать это или обходным путем?

(Изменить) Уточнение

Я хочу, чтобы функция фактического результата была общей. Если я сделаю

 fun <T: Any> prefixer(prefix: String): (String, KClass<T>) -> T { TODO() } 

как показывают текущие ответы; Я не получаю общую функцию, вместо этого получаю (String, KClass<Foo>) -> Foo если я вызываю prefixer<Foo>("") . Таким образом, эту функцию можно вызывать только с помощью Foo , в то время как prefixer фабричной функции в этом случае является общим, результата нет. Надеюсь, это устранит недоразумения.

Мой вариант использования находится в плагине Gradle, где я написал вспомогательный метод, подобный этому, который применяет некоторые значения по умолчанию для каждой созданной задачи:

 val myPrefix = "..." val project: Project = <from context> fun <T: Task> String.task(type: KClass<T>, doConfig: T.() -> Unit) { project.tasks.create("$prefix$this", type.java, { it.doConfig() }) } 

Обратите внимание, что проект приходит как закрытие. Теперь я хочу повторно использовать этого помощника в другом плагине, поэтому я хотел бы создать эту функцию, используя фабрику для разных экземпляров проекта.

Вы делаете это почти правильно. Вам нужно только определить общую часть функции prefixer напрямую.

 fun <T: Any> prefixer(prefix: String): (String, KClass<T>) -> T { TODO() } 

В зависимости от вашей фактической реализации вы можете взглянуть на ключевое слово reified .

Следующая строка компилирует:

 fun <T : Any> prefixer(prefix: String): (String, KClass<T>) -> T = TODO() 

Во-первых, общее замедление должно быть сразу после ключевого слова fun.

Затем он должен быть объявлен как тип Any. По умолчанию используется Any? но KClass принимает только Any.

Нет, это невозможно (насколько я знаю). Технический термин для такого типа – «тип более высокого типа», и очень немногие языки поддерживают их, на JVM я знаю только Scala.

Если кто-то задал мне тот же вопрос без интерфейса, например Factory , я бы предложил создать именно этот интерфейс в качестве обходного пути.