这个人为的例子说明了我的问题的本质:
trait Producer[X] {def make(): X }
sealed trait MyProducer[X] extends Producer[X]
case class MyProducerA(n: Int) extends MyProducer[Int] {...}
case class MyProducerB(s: String) extends MyProducer[String] {...}
def doWithProducer[P <: Producer[_]](producer: P): P = {
makePair(producer) // the compiler fails to infer the type parameter
producer
}
def makePair[X](p: Producer[X]): (X, X) = (p.make(), p.make())
// this is how I need to call the method
val myProducer: MyProducer[_] = ???
doWithProducer(myProducer)
doWithProducer()
方法不能具有产品类型的类型参数,因为MyProducer
的子类型具有不同的产品类型(或者我在这里已经错了吗?)。在doWithProduct()
内部,我知道我有一个具有类型参数的Producer的具体实例。我不在乎,但有一个。但是,编译器无法解决这个问题。
是否可以在不更改方法签名的情况下解决此问题?
更新:我感到好奇,并促使我认为必须采用一种方法,就是我实际上可以在类型变量中间接捕获产品的类型:
def duplicate[X](p: X): (X, X) = (p, p)
duplicate(producer.make)
但是,我仍然无法进入Producer[X]
。
答案 0 :(得分:2)
P <: Producer[_]
表示P
是某些未知类型的生产者。如果您想说P
是要推断的某些已知类型的生产者,则不要使用存在类型。
尝试
def doWithProducer[X, P <: Producer[X]](producer: P): P = {
makePair(producer)
producer
}
或
def makePair(p: Producer[_]): (Any, Any) = (p.make(), p.make())
您必须更改方法doWithProducer
,makePair
中的至少一个的签名才能使其编译。
或者您可以投射
def doWithProducer[P <: Producer[_]](producer: P): P = {
makePair(producer.asInstanceOf[Producer[Any]])
producer
}