【发布时间】:2017-10-23 08:34:18
【问题描述】:
在 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 中出现其自身的问题)。 我想将前缀转换为 kotlin 函数,但似乎不可能将泛型函数声明为返回类型:
fun prefixer(prefix: String): <T> (String, KClass<T>) -> T { TODO() }
这当然不能编译。在我看来,与 Java 的功能接口相比,这是一个限制。有没有办法做到这一点,或者解决方法?
(编辑)澄清
我希望实际结果函数是通用的。如果我这样做了
fun <T: Any> prefixer(prefix: String): (String, KClass<T>) -> T { TODO() }
正如当前答案所暗示的那样;我没有得到通用函数,而是在调用prefixer<Foo>("") 时得到(String, KClass<Foo>) -> 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() })
}
请注意,该项目以闭包形式出现。现在我想在不同的插件中重用那个帮助器,所以我想为不同的项目实例使用工厂创建这个函数。
【问题讨论】:
标签: function generics lambda kotlin