Can scala';s类型泛型找出匹配/案例?

Can scala';s类型泛型找出匹配/案例?,scala,types,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={

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

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
返回b时出现类似错误。我意识到我可以将返回类型设置为Any,但在我的“real”代码中,我以递归下降的方式应用该函数,因此它将迫使我添加相当多的
作为
的替代,这是我想要避免的

有没有可能让Scala的类型系统知道我要写什么,而不必完全重写函数

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

  • 事实上,它是递归的

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


您可以在报税表中添加一个INSTANCEOF。这会导致生产代码出现问题吗

比如:

def printStuff[T](obj:T):T={
    obj match{
      case a:A=>{ a.printA
        a.asInstanceOf[T]
      }
      case b:B=>{ b.printB
        b.asInstanceOf[T]
      }
    }
  }

您可以在报税表中添加一个INSTANCEOF。这会导致生产代码出现问题吗

比如:

def printStuff[T](obj:T):T={
    obj match{
      case a:A=>{ a.printA
        a.asInstanceOf[T]
      }
      case b:B=>{ b.printB
        b.asInstanceOf[T]
      }
    }
  }

为什么不简单地为每种参数类型重载
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)

为什么不简单地为每种参数类型重载
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)

为什么
printStuff()
末尾的
return obj
return
关键字不是必需的)不可行?在我的生产代码中,我很少返回相同的对象,而是构造其他对象。我尝试更新示例以清除这一部分。当我将上面为我编译的代码粘贴到REPLWhy
return obj
return
关键字不是必需的)的
printStuff()
末尾时,我很少返回相同的对象,而是构造其他对象。我已经尝试更新示例以清除这部分内容。当我将上面的代码粘贴到repl中时,我为我编译了许多不同的代码(大约20个),我真的试图避免走这条路线(这似乎与scala的方式相反),我真的认为如果没有显式转换(isInstanceOf),就无法做到这一点,或者让所有类共享一个公共类型(实现接口?),或者使用Any作为返回类型。Scala无法对根据传递的值和类型匹配构造返回不同类型的方法进行类型检查。当然,我可能是错的。我的生产代码中有很多不同的情况(可能是20种左右),我真的会尽量避免走这条路(这似乎与scala的方式相反),我真的认为如果没有显式转换(isInstanceOf),或者让所有类共享一个公共类型(实现接口?),就无法做到这一点,或者使用Any作为返回类型。Scala无法对根据传递的值和类型匹配构造返回不同类型的方法进行类型检查。当然,我可能错了。在我看来,typeclass绝对是正确的方法。我相当确定,返回类型与输入一致的公共接口才是真正需要的,问题是试图在一个地方实现它。在我看来,typeclass绝对是正确的方法。我相当肯定,返回类型与输入一致的公共接口才是真正需要的,问题是试图在一个地方实现它。