2

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

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

Java 对 this 的定义总结如下(稍作改写):

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 抱怨 [ , ] 对于 getOneThing的 [I <: Id[I,T],T <: Thing[I,T]] 来说不够好() 要求:

... 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 声明非参数化(非泛型)基类并没有真正帮助,因为它只会将问题推到(太多)其他地方。我们选择了非常严格的类型以确保代码质量,但我们确实必须有一种方法来处理“混合”集合。

有什么帮助吗?请!

4

1 回答 1

2

我假设你有这样的方法:

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

这将给出一个错误,因为编译器无法推断您想要调用该getOneThing方法T作为第二个类型参数。

为了“帮助”编译器,您需要明确地传递它们:

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](_) )
于 2013-04-20T23:15:18.467 回答