在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() })
}
请注意,该项目作为闭包进入 . 现在我想在不同的插件中重用该帮助器,因此我想使用工厂为不同的项目实例创建此函数 .
3 回答
不,这是不可能的(据我所知) . 这种类型的技术术语是“更高级的类型”,很少有语言支持它们,在JVM上我只知道Scala .
如果有人在没有像
Factory
这样的界面的情况下问我同样的问题,我建议创建这个界面作为解决方法 .你几乎正确地做到了 . 您只需要直接在
prefixer
函数中定义通用部分 .根据您的实际实现,您可以查看reified关键字 .
以下行确实编译:
首先,通用减速应该在fun关键字之后 .
然后必须将其声明为Any类型 . 默认是Any?但KClass只需要任何 .