0

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

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,但是在我的“真实”代码中,我以递归下降的方式应用该函数,所以它会迫使我添加很多asInstanceOfs,这是我想要的避免。

是否有可能让 Scala 的类型系统找出我正在尝试编写的内容,而无需完全重写该函数?

编辑:我试图编辑我的示例以显示在我的真实代码中可能很重要的东西:

  • 它是递归的事实

  • 它的返回类型取决于参数之一的事实。

4

2 回答 2

3

为什么不简单地printStuff为每个参数类型重载,因为这实际上就是你正在做的事情?

def printStuff(a : A) = {a.printA; new A(Some(a))}
def printStuff(b : B) = {b.printB; new B(b.someValue - 1)}

或者,如果您想抽象出一些常见的行为,因此保留单个方法,您可以沿着 typeclass 路线走:

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)
于 2012-08-14T17:05:47.673 回答
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]
      }
    }
  }
于 2012-08-14T16:34:51.937 回答