在Scala 2.10中泛化的generics

在Scala中缺乏具体的generics是最让我感到困惑的,因为简单的东西不能使用复杂的构造来实现。

Kotlin和Ceylon都支持泛化的generics,所以它绝对可以在JVM之上这样做。 过去有人说,如果没有JVM的改变,Scala就不能支持它们,但是现在Scala 2.10被传言对于物化的支持有限。 所以我的问题是:

  • 我们可以期望在Scala 2.10中实现物化,例如,我能否多次实现一个通用的特性 ? 它是多么有限?
  • 如果斯卡拉2.10的物化结果比科特林和锡兰更有限。 这是为什么 ?

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

  • 泛化的generics

所以,请原谅,但实施certificate是可能的? 事实上,我对Kotlin的前途并不十分看好,但是锡兰的前景如何,正如已经提供的那样,却是透明的。

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

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

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

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

接下来,让我们看看方法handle 。 同样,JVM不提供在方法定义中使用types参数的方法。 实现这一点的唯一方法是将接受Object作为参数handle :即键入擦除。

这里的处理是:使得handle从Java调用,它必须被删除。 而且,如果它被删除,那么它受到你问题中所描述的限制。 解决这个问题的唯一方法就是放弃Java的兼容性(顺便说一句,在Ceylon的第一个版本中也不可用)。

是的,根据马丁·奥德斯基(Martin Odersky)的说法,斯卡拉将在2.10版本上有所化身。 但无论它提供了什么(我敢打赌更加透明地使用清单来声明types相等),这个特殊的限制是JVM所固有的,并且不能在不减少Java集成的情况下被克服。

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

Kotlin已经为内联函数types参数统一了generics,如下所示: https : //kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters 。 这在Kotlin已经存在了一段时间了,已经被Kotlin生态系统中的许多图书馆所使用。 其他答案在提及Kotlin时已经过时了。 自2016年2月以来,Kotlin已经发布为1.0。

在Jackson Kotlin模块中使用的Kotlin中着名的TypeReference中的TypeReferencegenerics的示例使用以下代码:

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

而基于Kotlin的Injekt库也是这样:

 public inline fun  fullType(): FullTypeReference = object:FullTypeReference(){} public inline fun  injectLazy(): Lazy { return lazy { Injekt.get(fullType()) } } 

根据安德烈·布雷斯拉夫在这个页面上所说的话,科特林没有具体的types:

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