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