scala的类型泛型可以找出匹配/案例吗?

时间:2012-08-14 16:26:09

标签: scala types

我有一些类似于以下内容的代码:

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的类型系统弄清楚我正在尝试编写什么,而不必完全重写函数?

编辑:我试图编辑我的示例,以显示在我的实际代码中可能很重要的内容:

  • 这是递归的事实

  • 其返回类型取决于其中一个参数。

2 个答案:

答案 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]
      }
    }
  }