我有一些类似于以下内容的代码:
class testClass {
class A(val next:Option[A]){
def printA=println("A called")
}
class B(val someValue:Int){
def printB=println("B called with value "+someValue)
}
def printStuff[T](obj:T):Any={
obj match{
case a:A=>{ a.printA
return new A(Some(a))
}
case b:B=>{ b.printB
return if (b.someValue==0) new B(0) else
printStuff(new B(b.someValue-1))
}
}
}
在这里,我希望我的方法printStuff返回一个与输入类型相同的对象。但是,在尝试编译时,我收到以下错误:
error: type mismatch;
found : a.type (with underlying type testClass.this.A)
required: T
return a
return b
出现类似错误。我意识到我可以将返回类型设置为Any,但在我的“真实”代码中,我以递归下降的方式应用函数,因此它会强制我添加相当多的asInstanceOf
s,我想避免。
是否有可能让Scala的类型系统弄清楚我正在尝试编写什么,而不必完全重写函数?
编辑:我试图编辑我的示例,以显示在我的实际代码中可能很重要的内容:
这是递归的事实
其返回类型取决于其中一个参数。
答案 0 :(得分:3)
为什么不简单地为每个参数类型重载printStuff
,因为这实际上是你正在做的事情?
def printStuff(a : A) = {a.printA; new A(Some(a))}
def printStuff(b : B) = {b.printB; new B(b.someValue - 1)}
或者,如果您想要抽象出来的常见行为,那么保留单个方法,您可以沿着类型类路径:
trait Cloneable[T] { def clone(t : T) : T }
object Cloneable {
implicit object AIsCloneable extends Cloneable[A] { def clone(a : A) = new A(Some(a)) }
implicit object BIsCloneable extends Cloneable[B] { def clone(b : B) : B = if (b.someValue == 0) new B(0) else new B(b.someValue -1) }
}
def printStuff[T : Cloneable](t : T) = implicitly[Cloneable[T]].clone(t)
答案 1 :(得分:0)
您可以在返回时添加asInstanceOf。这会导致您的生产代码出现问题吗?
类似的东西:
def printStuff[T](obj:T):T={
obj match{
case a:A=>{ a.printA
a.asInstanceOf[T]
}
case b:B=>{ b.printB
b.asInstanceOf[T]
}
}
}