scala - 在 Scala 2.10 中使用混合复杂 Java 泛型集合

标签 scala scala-2.10 scala-java-interop

在我工作的公司中,我们从(Java)模式中获得了很多好处,可以总结如下:

我们可以通过他们的特殊/智能“id”来获取一些“东西”。每个“事物”都知道它的 id,而 id 是“智能”的,因为您可以要求它们向您提供它们识别的“事物”。在复杂且不断增长的“事物”层次结构中,这简化了维护并消除了大量代码(重复和其他代码)。我确信你们中的一些人可能会觉得这很奇怪,我可以解释为什么会这样,但事实是它是这样的,到目前为止它很有帮助,并且不是问题的一部分。

Java 定义总结如下(稍作重写):

interface Id<I extends Id<I,T>, T extends Thing<I,T>> {
  T getThing();
  ...
}

interface Thing<I extends Id<I,T>, T extends Thing<I,T>> {
  public I getId();
  ...
}

有时,我们需要在给定一批不同 ID 的情况下获取“一批”事物(这会跨网络,因此通过批处理来加快速度)。为了描述的目的,它可以写成:

public Map<Id<?,?>,Thing<?,?>> getManyThings(List<Id<?,?>> idsToGetThingsFor);

(方法参数只是多个 id,它是集合、列表还是其他形式并不重要)

现在,在网络的另一端,这个方法在 Scala 2.9 中实现,相当难看地避免了 Scala 泛型的严格性。我们正在尝试升级到 Scala 2.10,但事情不再编译,必须找到一种方法来处理这个问题。诀窍是有一个Scala方法总结如下:

def getOneThing[I <: Id[I,T],T <: Thing[I,T]](id: I): T;

该方法根据许多因素适本地检查、处理和分配调用 - 此处解释太多且无关紧要。

现在, getManyThings() 方法会迭代传递给它的 id,并且需要将它们作为参数传递给 getOneThing()。这就是事情失败的地方。 getManyThings() 只知道它获取的 id 本质上是 Id[,],Scala 提示 [,] 对于 [I <: Id[I,T] 来说不够好],T <: Thing[I,T]] getOneThing() 需要:

... error: inferred type arguments [Id[_$16,_$17],Nothing] do not conform to method getOneThing's type parameter bounds [I <: Id[I,T],T <: Thing[I,T]]

注意 - 为 Id 和 Thing 声明非参数化(非泛型)基类并没有真正的帮助,因为它只会将问题推向(太多)其他地方。我们选择非常严格的类型来确保代码质量,但我们确实必须有一种方法来处理“混合”集合。

有什么帮助吗?请!

最佳答案

我假设你有这样的方法:

def getManyThings[I <: Id[I, T], T <: Thing[I, T]](ids:List[I]):List[T] = 
  ids map getOneThing

这会产生错误,因为编译器无法推断您想要使用 T 作为第二个类型参数来调用 getOneThing 方法。

为了“帮助”编译器,您需要显式传递它们:

trait Id[I <: Id[I, T], T <: Thing[I, T]]
trait Thing[I <: Id[I, T], T <: Thing[I, T]]

def getOneThing[I <: Id[I, T], T <: Thing[I, T]](id:I):T = ???

def getManyThings[I <: Id[I, T], T <: Thing[I, T]](ids:List[I]):List[T] = 
  ids map ( getOneThing[I, T](_) )

关于scala - 在 Scala 2.10 中使用混合复杂 Java 泛型集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16122154/

相关文章:

scala - 为什么我必须在此函数中包含额外的类型信息

scala - 注释掉Scala中的部分代码

performance - 在哪种情况下,Scala 2.10.0 编译器可以比 2.9.2 更快或更慢?

scala - Scala 中 == 和 .equals 有什么区别?

scala - 获取类属性或类函数的名称作为字符串

scala - Play war 部署导致 Tomcat 停止

scala - Json Coast to Coast Play框架: Serializing Joda DateTime

scala - 在scala中获取当前文件的文件名

java - 从 Scala 代码调用 java 通用 Java 方法时类型不匹配

Scala:覆盖通用 Java 方法 II