28

Scala 中缺乏具体化的泛型是这门语言最困扰我的地方,因为如果不使用复杂的构造,简单的事情就无法实现。

Kotlin 和 Ceylon 都支持物化泛型,因此绝对可以在 JVM 之上这样做。过去据说 Scala 不能在不改变 JVM 的情况下支持它们,但现在传闻 Scala 2.10具体化的支持有限。所以我的问题是:

  • 我们可以期待在 Scala 2.10 中具体化什么,例如,我是否能够多次实现一个通用特征?它到底有多有限?
  • 如果 Scala 2.10 的具体化结果比KotlinCeylon更有限。这是为什么 ?
4

3 回答 3

31

你的论点有缺陷。Kotlin 还没有发布*,Ceylon 刚刚发布了它的第一个版本,我将引用他们的公告中缺少的一个东西:

  • 物化泛型

所以,对不起,但是什么实现证明它是可能的?事实上,我并没有过多关注 Kotlin 的承诺,但Ceylon所承诺的正是 manifest 已经提供的东西,而且是以透明的方式提供的。

但是让我们考虑一下您在问题中描述的问题:

trait Handles[E <: Event] {
  def handle(event: E)
}

所以,首先,JVM没有提供任何识别接口或类中类型参数的方法,所以E 不能被JVM检查。但是,您可以存储有关Eimplementations 的每个对象中代表的信息Handles,就像您可以在 Scala 中编写此代码一样:

abstract class Handles[E <: Event : Manifest] {
  def handle(event: E)
}

接下来,我们来看看方法handle。同样,JVM 没有提供在方法定义中使用类型参数的方法。实现它的唯一方法是将handle接受Object作为参数:即类型擦除。

交易是这样的:handle要从 Java 中调用,它必须被类型擦除。而且,如果它被类型擦除,那么它会受到您问题中描述的限制。解决这个问题的唯一方法是放弃 Java 兼容性(顺便说一句,这在 Ceylon 的第一个版本中也不可用)。

是的,根据 Martin Odersky 的说法,Scala 将在 2.10 上进行(某种形式的)具体化。但无论它提供什么(我打赌更透明地使用清单来断言类型相等),这个特殊的限制是 JVM 固有的,如果不放弃 Java 集成就无法克服。

(*) Kotlin 现在有一个演示,它的具体化——到目前为止——只是捆绑清单和 instanceOf 测试的语法糖。它仍然受到 Scala 的所有相同限制。

于 2011-12-22T19:24:38.283 回答
9

Kotlin 已经为内联函数类型参数重新定义了泛型,如下所述:https ://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters 。这在 Kotlin 中已经存在了一段时间,它们已被 Kotlin 生态系统中的许多库使用。当提到 Kotlin 时,这里的其他答案已经过时了。 自 2016 年 2 月以来,Kotlin 已作为 1.0 发布。

Kotlin 中的具体化泛型示例,在 Jackson 中很有名TypeReference,在Jackson Kotlin 模块中使用时使用以下代码:

public inline fun <reified T: Any> ObjectMapper.readValue(jp: JsonParser): T 
     = readValue(jp, object: TypeReference<T>() {})

同样来自基于 Kotlin 的Injekt库:

public inline fun <reified T: Any> fullType(): FullTypeReference<T> 
    = object:FullTypeReference<T>(){}

public inline fun <reified T : Any> injectLazy(): Lazy<T> {
    return lazy { Injekt.get(fullType<T>()) }
}
于 2015-12-29T04:34:04.350 回答
2

根据 Andrey Breslav 在页面上所说的,Kotlin 没有具体类型:

“是的,类型参数在类对象中不可用”

于 2012-11-27T10:06:32.760 回答